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 2 : BackingComp::BackingComp( const css::uno::Reference< css::uno::XComponentContext >& xContext )
152 2 : : m_xContext(xContext)
153 : {
154 2 : }
155 :
156 :
157 :
158 4 : BackingComp::~BackingComp()
159 : {
160 4 : }
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 132 : css::uno::Any SAL_CALL BackingComp::queryInterface( /*IN*/ const css::uno::Type& aType )
180 : throw(css::uno::RuntimeException, std::exception)
181 : {
182 132 : css::uno::Any aResult;
183 :
184 : // first look for own supported interfaces
185 264 : 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 132 : 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 132 : if (!aResult.hasValue())
201 : {
202 : /* SAFE { */
203 68 : SolarMutexGuard aGuard;
204 68 : if (m_xWindow.is())
205 68 : aResult = m_xWindow->queryInterface(aType);
206 : /* } SAFE */
207 : }
208 :
209 : // look for XWeak and XInterface
210 132 : if (!aResult.hasValue())
211 62 : aResult = OWeakObject::queryInterface(aType);
212 :
213 132 : return aResult;
214 : }
215 :
216 :
217 :
218 : /** increase ref count of this instance.
219 : */
220 :
221 272 : void SAL_CALL BackingComp::acquire()
222 : throw()
223 : {
224 272 : OWeakObject::acquire();
225 272 : }
226 :
227 :
228 :
229 : /** decrease ref count of this instance.
230 : */
231 :
232 272 : void SAL_CALL BackingComp::release()
233 : throw()
234 : {
235 272 : OWeakObject::release();
236 272 : }
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 : cppu::UnoType<css::lang::XInitialization>::get(),
272 0 : cppu::UnoType<css::lang::XTypeProvider>::get(),
273 0 : cppu::UnoType<css::lang::XServiceInfo>::get(),
274 0 : cppu::UnoType<css::frame::XController>::get(),
275 0 : cppu::UnoType<css::lang::XComponent>::get(),
276 0 : cppu::UnoType<css::frame::XDispatchProvider>::get(),
277 0 : cppu::UnoType<css::frame::XDispatch>::get(),
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 322 : sal_Bool SAL_CALL BackingComp::supportsService( /*IN*/ const OUString& sServiceName )
312 : throw(css::uno::RuntimeException, std::exception)
313 : {
314 322 : return cppu::supportsService(this, sServiceName);
315 : }
316 :
317 322 : css::uno::Sequence< OUString > SAL_CALL BackingComp::getSupportedServiceNames()
318 : throw(css::uno::RuntimeException, std::exception)
319 : {
320 322 : css::uno::Sequence< OUString > lNames(2);
321 322 : lNames[0] = "com.sun.star.frame.StartModule";
322 322 : lNames[1] = "com.sun.star.frame.ProtocolHandler";
323 322 : return lNames;
324 : }
325 :
326 :
327 : /**
328 : attach this component to a target frame.
329 :
330 : We has to use the container window of this frame as parent window of our own component window.
331 : But it's not allowed to work with it really. May another component used it too.
332 : Currently we need it only to create our child component window and support it's
333 : interfaces inside our queryInterface() method. The user of us must have e.g. the
334 : XWindow interface of it to be able to call setComponent(xWindow,xController) at the
335 : frame!
336 :
337 : May he will do the following things:
338 :
339 : <listing>
340 : XController xBackingComp = (XController)UnoRuntime.queryInterface(
341 : XController.class,
342 : xSMGR.createInstance(SERVICENAME_STARTMODULE));
343 :
344 : // at this time XWindow isn't present at this instance!
345 : XWindow xBackingComp = (XWindow)UnoRuntime.queryInterface(
346 : XWindow.class,
347 : xBackingComp);
348 :
349 : // attach controller to the frame
350 : // We will use it's container window, to create
351 : // the component window. From now we offer the window interfaces!
352 : xBackingComp.attachFrame(xFrame);
353 :
354 : XWindow xBackingComp = (XWindow)UnoRuntime.queryInterface(
355 : XWindow.class,
356 : xBackingComp);
357 :
358 : // Our user can set us at the frame as new component
359 : xFrame.setComponent(xBackingWin, xBackingComp);
360 :
361 : // But that had no effect to our view state.
362 : // We must be started to create our UI elements like e.g. menu, title, background ...
363 : XInitialization xBackingInit = (XInitialization)UnoRuntime.queryInterface(
364 : XInitialization.class,
365 : xBackingComp);
366 :
367 : xBackingInit.initialize(lArgs);
368 : </listing>
369 :
370 : @param xFrame
371 : reference to our new target frame
372 :
373 : @throw com::sun::star::uno::RuntimeException
374 : if the given frame reference is wrong or component window couldn't be created
375 : successfully.
376 : We throw it too, if we already attached to a frame. Because we don't support
377 : reparenting of our component window on demand!
378 : */
379 :
380 2 : void SAL_CALL BackingComp::attachFrame( /*IN*/ const css::uno::Reference< css::frame::XFrame >& xFrame )
381 : throw (css::uno::RuntimeException, std::exception)
382 : {
383 : /* SAFE */
384 2 : SolarMutexGuard aGuard;
385 :
386 : // check some required states
387 2 : if (m_xFrame.is())
388 : throw css::uno::RuntimeException(
389 : OUString("already attached"),
390 0 : static_cast< ::cppu::OWeakObject* >(this));
391 :
392 2 : if (!xFrame.is())
393 : throw css::uno::RuntimeException(
394 : OUString("invalid frame reference"),
395 0 : static_cast< ::cppu::OWeakObject* >(this));
396 :
397 2 : if (!m_xWindow.is())
398 2 : return; // disposed
399 :
400 : // safe the frame reference
401 2 : m_xFrame = xFrame;
402 :
403 : // initialize the component and its parent window
404 4 : css::uno::Reference< css::awt::XWindow > xParentWindow = xFrame->getContainerWindow();
405 2 : WorkWindow* pParent = static_cast<WorkWindow*>(VCLUnoHelper::GetWindow(xParentWindow));
406 2 : vcl::Window* pWindow = VCLUnoHelper::GetWindow(m_xWindow);
407 :
408 : // disable full screen mode of the frame!
409 2 : if (pParent && pParent->IsFullScreenMode())
410 : {
411 0 : pParent->ShowFullScreenMode(false);
412 0 : pParent->SetMenuBarMode(MENUBAR_MODE_NORMAL);
413 : }
414 :
415 : // create the menu bar for the backing component
416 4 : css::uno::Reference< css::beans::XPropertySet > xPropSet(m_xFrame, css::uno::UNO_QUERY_THROW);
417 4 : css::uno::Reference< css::frame::XLayoutManager > xLayoutManager;
418 2 : xPropSet->getPropertyValue(FRAME_PROPNAME_LAYOUTMANAGER) >>= xLayoutManager;
419 2 : if (xLayoutManager.is())
420 : {
421 2 : xLayoutManager->lock();
422 2 : xLayoutManager->createElement("private:resource/menubar/menubar");
423 2 : xLayoutManager->unlock();
424 : }
425 :
426 2 : if (pWindow)
427 : {
428 : // set help ID for our canvas
429 2 : pWindow->SetHelpId(HID_BACKINGWINDOW);
430 : }
431 :
432 : // inform BackingWindow about frame
433 2 : BackingWindow* pBack = dynamic_cast<BackingWindow*>(pWindow );
434 2 : if( pBack )
435 2 : pBack->setOwningFrame( m_xFrame );
436 :
437 : // Set a minimum size for Start Center
438 2 : if( pParent && pBack )
439 : {
440 2 : long nMenuHeight = 0;
441 2 : vcl::Window* pMenu = pParent->GetWindow(WINDOW_NEXT);
442 2 : if( pMenu )
443 2 : nMenuHeight = pMenu->GetSizePixel().Height();
444 :
445 : pParent->SetMinOutputSizePixel(
446 : Size(
447 2 : pBack->get_width_request(),
448 4 : pBack->get_height_request() + nMenuHeight));
449 2 : }
450 :
451 : /* } SAFE */
452 : }
453 :
454 :
455 :
456 : /** not supported.
457 :
458 : This component does not know any model. It will be represented by a window and
459 : its controller only.
460 :
461 : return <FALSE/> every time.
462 : */
463 :
464 0 : sal_Bool SAL_CALL BackingComp::attachModel( /*IN*/ const css::uno::Reference< css::frame::XModel >& )
465 : throw (css::uno::RuntimeException, std::exception)
466 : {
467 0 : return sal_False;
468 : }
469 :
470 :
471 :
472 : /** not supported.
473 :
474 : This component does not know any model. It will be represented by a window and
475 : its controller only.
476 :
477 : return An empty reference every time.
478 : */
479 :
480 72 : css::uno::Reference< css::frame::XModel > SAL_CALL BackingComp::getModel()
481 : throw (css::uno::RuntimeException, std::exception)
482 : {
483 72 : return css::uno::Reference< css::frame::XModel >();
484 : }
485 :
486 :
487 :
488 : /** not supported.
489 :
490 : return An empty value.
491 : */
492 :
493 0 : css::uno::Any SAL_CALL BackingComp::getViewData()
494 : throw (css::uno::RuntimeException, std::exception)
495 : {
496 0 : return css::uno::Any();
497 : }
498 :
499 :
500 :
501 : /** not supported.
502 :
503 : @param aData
504 : not used.
505 : */
506 :
507 0 : void SAL_CALL BackingComp::restoreViewData( /*IN*/ const css::uno::Any& )
508 : throw (css::uno::RuntimeException, std::exception)
509 : {
510 0 : }
511 :
512 :
513 :
514 : /** returns the attached frame for this component.
515 :
516 : @see attachFrame()
517 :
518 : @return The internally saved frame reference.
519 : Can be null, if attachFrame() was not called before.
520 : */
521 :
522 0 : css::uno::Reference< css::frame::XFrame > SAL_CALL BackingComp::getFrame()
523 : throw (css::uno::RuntimeException, std::exception)
524 : {
525 : /* SAFE { */
526 0 : SolarMutexGuard aGuard;
527 0 : return m_xFrame;
528 : /* } SAFE */
529 : }
530 :
531 :
532 :
533 : /** ask controller for its current working state.
534 :
535 : If someone wishes to close this component, it must suspend the controller before.
536 : That will be a chance for it to disagree with that AND show any UI for a possible
537 : UI user.
538 :
539 : @param bSuspend
540 : If it's set to sal_True this controller should be suspended.
541 : sal_False will resuspend it.
542 :
543 : @return sal_True if the request could be finished successfully; sal_False otherwise.
544 : */
545 :
546 2 : sal_Bool SAL_CALL BackingComp::suspend( /*IN*/ sal_Bool )
547 : throw (css::uno::RuntimeException, std::exception)
548 : {
549 : /* FIXME ... implemented by using default :-( */
550 2 : return sal_True;
551 : }
552 :
553 :
554 :
555 : /** callback from our window member.
556 :
557 : Our internal saved window wish to die. It will be disposed from outside (may be the frame)
558 : and inform us. We must release its reference only here. Of course we check the given reference
559 : here and reject callback from unknown sources.
560 :
561 : Note: deregistration as listener isn't necessary here. The broadcaster do it automatically.
562 :
563 : @param aEvent
564 : describe the broadcaster of this callback
565 :
566 : @throw ::com::sun::star::uno::RuntimeException
567 : if the broadcaster doesn't represent the expected window reference.
568 : */
569 :
570 0 : void SAL_CALL BackingComp::disposing( /*IN*/ const css::lang::EventObject& aEvent )
571 : throw(css::uno::RuntimeException, std::exception)
572 : {
573 : // Attention: dont free m_pAccExec here! see comments inside dtor and
574 : // keyPressed() for further details.
575 :
576 : /* SAFE { */
577 0 : SolarMutexGuard aGuard;
578 :
579 0 : if (!aEvent.Source.is() || aEvent.Source!=m_xWindow || !m_xWindow.is())
580 : throw css::uno::RuntimeException(
581 : OUString("unexpected source or called twice"),
582 0 : static_cast< ::cppu::OWeakObject* >(this));
583 :
584 0 : m_xWindow = css::uno::Reference< css::awt::XWindow >();
585 :
586 : /* } SAFE */
587 0 : }
588 :
589 :
590 :
591 : /** kill this instance.
592 :
593 : It can be called from our owner frame only. But there is no possibility to check the calli.
594 : We have to release all our internal used resources and die. From this point we can throw
595 : DisposedExceptions for every further interface request ... but current implementation doesn`t do so ...
596 :
597 : */
598 :
599 2 : void SAL_CALL BackingComp::dispose()
600 : throw(css::uno::RuntimeException, std::exception)
601 : {
602 : /* SAFE { */
603 2 : SolarMutexGuard aGuard;
604 :
605 : // kill the menu
606 4 : css::util::URL aURL;
607 2 : aURL.Complete = ".uno:close";
608 4 : css::uno::Reference< css::util::XURLTransformer > xParser = css::util::URLTransformer::create(m_xContext);
609 2 : if (xParser.is())
610 2 : xParser->parseStrict(aURL);
611 :
612 4 : css::uno::Reference< css::frame::XDispatchProvider > xProvider(m_xFrame, css::uno::UNO_QUERY);
613 2 : if (xProvider.is())
614 : {
615 2 : css::uno::Reference< css::frame::XDispatch > xDispatch = xProvider->queryDispatch(aURL, SPECIALTARGET_MENUBAR, 0);
616 2 : if (xDispatch.is())
617 2 : xDispatch->dispatch(aURL, css::uno::Sequence< css::beans::PropertyValue>());
618 : }
619 :
620 : // stop listening at the window
621 2 : if (m_xWindow.is())
622 : {
623 2 : css::uno::Reference< css::lang::XComponent > xBroadcaster(m_xWindow, css::uno::UNO_QUERY);
624 2 : if (xBroadcaster.is())
625 : {
626 2 : css::uno::Reference< css::lang::XEventListener > xEventThis(static_cast< ::cppu::OWeakObject* >(this), css::uno::UNO_QUERY);
627 2 : xBroadcaster->removeEventListener(xEventThis);
628 : }
629 4 : css::uno::Reference< css::awt::XKeyListener > xKeyThis(static_cast< ::cppu::OWeakObject* >(this), css::uno::UNO_QUERY);
630 2 : m_xWindow->removeKeyListener(xKeyThis);
631 4 : m_xWindow = css::uno::Reference< css::awt::XWindow >();
632 : }
633 :
634 : // forget all other used references
635 2 : m_xFrame.clear();
636 4 : m_xContext.clear();
637 :
638 : /* } SAFE */
639 2 : }
640 :
641 :
642 :
643 : /** not supported.
644 :
645 : @param xListener
646 : not used.
647 :
648 : @throw ::com::sun::star::uno::RuntimeException
649 : because the listener expect to be holded alive by this container.
650 : We must inform it about this unsupported feature.
651 : */
652 :
653 0 : void SAL_CALL BackingComp::addEventListener( /*IN*/ const css::uno::Reference< css::lang::XEventListener >& )
654 : throw(css::uno::RuntimeException, std::exception)
655 : {
656 : throw css::uno::RuntimeException(
657 : OUString("not supported"),
658 0 : static_cast< ::cppu::OWeakObject* >(this));
659 : }
660 :
661 :
662 :
663 : /** not supported.
664 :
665 : Because registration is not supported too, we must do nothing here. Nobody can call this method really.
666 :
667 : @param xListener
668 : not used.
669 : */
670 :
671 0 : void SAL_CALL BackingComp::removeEventListener( /*IN*/ const css::uno::Reference< css::lang::XEventListener >& )
672 : throw(css::uno::RuntimeException, std::exception)
673 : {
674 0 : }
675 :
676 :
677 :
678 : /**
679 : force initialiation for this component.
680 :
681 : Inside attachFrame() we created our component window. But it was not allowed there, to
682 : initialitze it. E.g. the menu must be set at the container window of the frame, which
683 : is our parent window. But may at that time another component used it.
684 : That's why our creator has to inform us, when it's time to initialize us really.
685 : Currently only calling of this method must be done. But further implementatoins
686 : can use special in parameter to configure this initialization ...
687 :
688 : @param lArgs
689 : currently not used
690 :
691 : @throw com::sun::star::uno::RuntimeException
692 : if some resources are missing
693 : Means if may be attachedFrame() wasn't called before.
694 : */
695 :
696 2 : void SAL_CALL BackingComp::initialize( /*IN*/ const css::uno::Sequence< css::uno::Any >& lArgs )
697 : throw(css::uno::Exception, css::uno::RuntimeException, std::exception)
698 : {
699 : /* SAFE { */
700 2 : SolarMutexGuard aGuard;
701 :
702 2 : if (m_xWindow.is())
703 : throw css::uno::Exception(
704 : OUString("already initialized"),
705 0 : static_cast< ::cppu::OWeakObject* >(this));
706 :
707 4 : css::uno::Reference< css::awt::XWindow > xParentWindow;
708 2 : if (
709 4 : (lArgs.getLength()!=1 ) ||
710 4 : (!(lArgs[0] >>= xParentWindow)) ||
711 2 : (!xParentWindow.is() )
712 : )
713 : {
714 : throw css::uno::Exception(
715 : OUString("wrong or corrupt argument list"),
716 0 : static_cast< ::cppu::OWeakObject* >(this));
717 : }
718 :
719 : // create the component window
720 2 : vcl::Window* pParent = VCLUnoHelper::GetWindow(xParentWindow);
721 2 : vcl::Window* pWindow = new BackingWindow(pParent);
722 2 : m_xWindow = VCLUnoHelper::GetInterface(pWindow);
723 :
724 2 : if (!m_xWindow.is())
725 : throw css::uno::RuntimeException(
726 : OUString("couldn't create component window"),
727 0 : static_cast< ::cppu::OWeakObject* >(this));
728 :
729 : // start listening for window disposing
730 : // It's set at our owner frame as component window later too. So it will may be disposed there ...
731 4 : css::uno::Reference< css::lang::XComponent > xBroadcaster(m_xWindow, css::uno::UNO_QUERY);
732 2 : if (xBroadcaster.is())
733 2 : xBroadcaster->addEventListener(static_cast< css::lang::XEventListener* >(this));
734 :
735 4 : m_xWindow->setVisible(sal_True);
736 :
737 : /* } SAFE */
738 2 : }
739 :
740 :
741 :
742 : /**
743 : */
744 :
745 0 : void SAL_CALL BackingComp::keyPressed( /*IN*/ const css::awt::KeyEvent& )
746 : throw(css::uno::RuntimeException, std::exception)
747 : {
748 0 : }
749 :
750 :
751 :
752 : /**
753 : */
754 :
755 0 : void SAL_CALL BackingComp::keyReleased( /*IN*/ const css::awt::KeyEvent& )
756 : throw(css::uno::RuntimeException, std::exception)
757 : {
758 : /* Attention
759 : Please use keyPressed() instead of this method. Otherwhise it would be possible, that
760 : - a key input may be first switch to the backing mode
761 : - and this component register itself as key listener too
762 : - and it's first event will be a keyRealeased() for the already well known event, which switched to the backing mode!
763 : So it will be handled twice! document => backing mode => exit app ...
764 : */
765 0 : }
766 :
767 : // XDispatchProvider
768 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 )
769 : {
770 0 : css::uno::Reference< css::frame::XDispatch > xDispatch;
771 0 : if ( aURL.Protocol == "vnd.org.libreoffice.recentdocs:" )
772 0 : xDispatch = this;
773 :
774 0 : return xDispatch;
775 : }
776 :
777 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 )
778 : {
779 0 : sal_Int32 nCount = seqDescripts.getLength();
780 0 : css::uno::Sequence < css::uno::Reference < XDispatch > > lDispatcher( nCount );
781 :
782 0 : for( sal_Int32 i=0; i<nCount; ++i )
783 0 : lDispatcher[i] = queryDispatch( seqDescripts[i].FeatureURL, seqDescripts[i].FrameName, seqDescripts[i].SearchFlags );
784 :
785 0 : return lDispatcher;
786 : }
787 :
788 : // XDispatch
789 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 )
790 : {
791 : // vnd.org.libreoffice.recentdocs:ClearRecentFileList - clear recent files
792 0 : if ( aURL.Path == "ClearRecentFileList" )
793 : {
794 0 : vcl::Window* pWindow = VCLUnoHelper::GetWindow(m_xWindow);
795 0 : BackingWindow* pBack = dynamic_cast<BackingWindow*>(pWindow );
796 0 : if( pBack )
797 : {
798 0 : pBack->clearRecentFileList();
799 :
800 : // Recalculate minimum width
801 0 : css::uno::Reference< css::awt::XWindow > xParentWindow = m_xFrame->getContainerWindow();
802 0 : WorkWindow* pParent = static_cast<WorkWindow*>(VCLUnoHelper::GetWindow(xParentWindow));
803 0 : if( pParent )
804 : {
805 : pParent->SetMinOutputSizePixel( Size(
806 0 : pBack->get_width_request(),
807 0 : pParent->GetMinOutputSizePixel().Height()) );
808 0 : }
809 : }
810 : }
811 0 : }
812 :
813 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 )
814 : {
815 0 : }
816 :
817 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 )
818 : {
819 0 : }
820 :
821 : }
822 :
823 : extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface * SAL_CALL
824 2 : com_sun_star_comp_sfx2_BackingComp_get_implementation(
825 : css::uno::XComponentContext *context,
826 : css::uno::Sequence<css::uno::Any> const &)
827 : {
828 2 : return cppu::acquire(new BackingComp(context));
829 951 : }
830 :
831 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|