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/queryinterface.hxx>
46 : #include <cppuhelper/typeprovider.hxx>
47 : #include <toolkit/helper/vclunohelper.hxx>
48 : #include <vcl/keycod.hxx>
49 : #include <vcl/wrkwin.hxx>
50 : #include <vcl/svapp.hxx>
51 : #include <rtl/ref.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 :
62 : namespace {
63 :
64 : const char FRAME_PROPNAME_LAYOUTMANAGER[] = "LayoutManager";
65 : const char HID_BACKINGWINDOW[] = "FWK_HID_BACKINGWINDOW";
66 : const char SPECIALTARGET_MENUBAR[] = "_menubar";
67 :
68 : /**
69 : implements the backing component.
70 :
71 : This component is a special one, which doesn't provide a controller
72 : nor a model. It supports the following features:
73 : - Drag & Drop
74 : - Key Accelerators
75 : - Simple Menu
76 : - Progress Bar
77 : - Background
78 : */
79 : class BackingComp : public css::lang::XTypeProvider
80 : , public css::lang::XServiceInfo
81 : , public css::lang::XInitialization
82 : , public css::frame::XController // => XComponent
83 : , public css::awt::XKeyListener // => XEventListener
84 : , public css::frame::XDispatchProvider
85 : , public css::frame::XDispatch
86 : , public ::cppu::OWeakObject
87 : {
88 : private:
89 : /** the global uno service manager.
90 : Must be used to create own needed services. */
91 : css::uno::Reference< css::uno::XComponentContext > m_xContext;
92 :
93 : /** reference to the component window. */
94 : css::uno::Reference< css::awt::XWindow > m_xWindow;
95 :
96 : /** the owner frame of this component. */
97 : css::uno::Reference< css::frame::XFrame > m_xFrame;
98 :
99 : public:
100 :
101 : BackingComp( const css::uno::Reference< css::uno::XComponentContext >& xContext );
102 : virtual ~BackingComp( );
103 :
104 : // XInterface
105 : virtual css::uno::Any SAL_CALL queryInterface( const css::uno::Type& aType ) throw(css::uno::RuntimeException, std::exception) SAL_OVERRIDE;
106 : virtual void SAL_CALL acquire ( ) throw( ) SAL_OVERRIDE;
107 : virtual void SAL_CALL release ( ) throw( ) SAL_OVERRIDE;
108 :
109 : // XTypeProvide
110 : virtual css::uno::Sequence< css::uno::Type > SAL_CALL getTypes () throw(css::uno::RuntimeException, std::exception) SAL_OVERRIDE;
111 : virtual css::uno::Sequence< sal_Int8 > SAL_CALL getImplementationId() throw(css::uno::RuntimeException, std::exception) SAL_OVERRIDE;
112 :
113 : // XServiceInfo
114 : virtual OUString SAL_CALL getImplementationName ( ) throw(css::uno::RuntimeException, std::exception) SAL_OVERRIDE;
115 : virtual sal_Bool SAL_CALL supportsService ( const OUString& sServiceName ) throw(css::uno::RuntimeException, std::exception) SAL_OVERRIDE;
116 : virtual css::uno::Sequence< OUString > SAL_CALL getSupportedServiceNames( ) throw(css::uno::RuntimeException, std::exception) SAL_OVERRIDE;
117 :
118 : // XInitialization
119 : virtual void SAL_CALL initialize( const css::uno::Sequence< css::uno::Any >& lArgs ) throw(css::uno::Exception, css::uno::RuntimeException, std::exception) SAL_OVERRIDE;
120 :
121 : // XController
122 : virtual void SAL_CALL attachFrame( const css::uno::Reference< css::frame::XFrame >& xFrame ) throw(css::uno::RuntimeException, std::exception) SAL_OVERRIDE;
123 : virtual sal_Bool SAL_CALL attachModel( const css::uno::Reference< css::frame::XModel >& xModel ) throw(css::uno::RuntimeException, std::exception) SAL_OVERRIDE;
124 : virtual sal_Bool SAL_CALL suspend( sal_Bool bSuspend ) throw(css::uno::RuntimeException, std::exception) SAL_OVERRIDE;
125 : virtual css::uno::Any SAL_CALL getViewData() throw(css::uno::RuntimeException, std::exception) SAL_OVERRIDE;
126 : virtual void SAL_CALL restoreViewData( const css::uno::Any& aData ) throw(css::uno::RuntimeException, std::exception) SAL_OVERRIDE;
127 : virtual css::uno::Reference< css::frame::XModel > SAL_CALL getModel() throw(css::uno::RuntimeException, std::exception) SAL_OVERRIDE;
128 : virtual css::uno::Reference< css::frame::XFrame > SAL_CALL getFrame() throw(css::uno::RuntimeException, std::exception) SAL_OVERRIDE;
129 :
130 : // XKeyListener
131 : virtual void SAL_CALL keyPressed ( const css::awt::KeyEvent& aEvent ) throw(css::uno::RuntimeException, std::exception) SAL_OVERRIDE;
132 : virtual void SAL_CALL keyReleased( const css::awt::KeyEvent& aEvent ) throw(css::uno::RuntimeException, std::exception) SAL_OVERRIDE;
133 :
134 : // XEventListener
135 : virtual void SAL_CALL disposing( const css::lang::EventObject& aEvent ) throw(css::uno::RuntimeException, std::exception) SAL_OVERRIDE;
136 :
137 : // XComponent
138 : virtual void SAL_CALL dispose ( ) throw(css::uno::RuntimeException, std::exception) SAL_OVERRIDE;
139 : virtual void SAL_CALL addEventListener ( const css::uno::Reference< css::lang::XEventListener >& xListener ) throw(css::uno::RuntimeException, std::exception) SAL_OVERRIDE;
140 : virtual void SAL_CALL removeEventListener( const css::uno::Reference< css::lang::XEventListener >& xListener ) throw(css::uno::RuntimeException, std::exception) SAL_OVERRIDE;
141 :
142 : // XDispatchProvider
143 : 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;
144 : 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;
145 :
146 : // XDispatch
147 : 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;
148 : 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;
149 : 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;
150 : };
151 :
152 2 : BackingComp::BackingComp( const css::uno::Reference< css::uno::XComponentContext >& xContext )
153 2 : : m_xContext(xContext)
154 : {
155 2 : }
156 :
157 :
158 :
159 4 : BackingComp::~BackingComp()
160 : {
161 4 : }
162 :
163 :
164 :
165 : /** return information about supported interfaces.
166 :
167 : Some interfaces are supported by his class directly, but some other ones are
168 : used by aggregation. An instance of this class must provide some window interfaces.
169 : But it must represent a VCL window behind such interfaces too! So we use an internal
170 : saved window member to ask it for it's interfaces and return it. But we must be aware then,
171 : that it can be destroyed from outside too ...
172 :
173 : @param aType
174 : describe the required interface type
175 :
176 : @return An Any holding the instance, which provides the queried interface.
177 : Note: There exist two possible results ... this instance itself and her window member!
178 : */
179 :
180 68 : css::uno::Any SAL_CALL BackingComp::queryInterface( /*IN*/ const css::uno::Type& aType )
181 : throw(css::uno::RuntimeException, std::exception)
182 : {
183 68 : css::uno::Any aResult;
184 :
185 : // first look for own supported interfaces
186 136 : aResult = ::cppu::queryInterface(
187 : aType,
188 : static_cast< css::lang::XTypeProvider* >(this),
189 : static_cast< css::lang::XServiceInfo* >(this),
190 : static_cast< css::lang::XInitialization* >(this),
191 : static_cast< css::frame::XController* >(this),
192 : static_cast< css::lang::XComponent* >(this),
193 : static_cast< css::lang::XEventListener* >(this),
194 : static_cast< css::awt::XKeyListener* >(static_cast< css::lang::XEventListener* >(this)),
195 : static_cast< css::frame::XDispatchProvider* >(this),
196 68 : static_cast< css::frame::XDispatch* >(this) );
197 :
198 : // then look for supported window interfaces
199 : // Note: They exist only, if this instance was initialized
200 : // with a valid window reference. It's aggregation on demand ...
201 68 : if (!aResult.hasValue())
202 : {
203 : /* SAFE { */
204 34 : SolarMutexGuard aGuard;
205 34 : if (m_xWindow.is())
206 34 : aResult = m_xWindow->queryInterface(aType);
207 : /* } SAFE */
208 : }
209 :
210 : // look for XWeak and XInterface
211 68 : if (!aResult.hasValue())
212 31 : aResult = OWeakObject::queryInterface(aType);
213 :
214 68 : return aResult;
215 : }
216 :
217 :
218 :
219 : /** increase ref count of this instance.
220 : */
221 :
222 145 : void SAL_CALL BackingComp::acquire()
223 : throw()
224 : {
225 145 : OWeakObject::acquire();
226 145 : }
227 :
228 :
229 :
230 : /** decrease ref count of this instance.
231 : */
232 :
233 145 : void SAL_CALL BackingComp::release()
234 : throw()
235 : {
236 145 : OWeakObject::release();
237 145 : }
238 :
239 :
240 :
241 : /** return collection about all supported interfaces.
242 :
243 : Optimize this method !
244 : We initialize a static variable only one time.
245 : And we don't must use a mutex at every call!
246 : For the first call; pTypeCollection is NULL -
247 : for the second call pTypeCollection is different from NULL!
248 :
249 : @return A list of all supported interface types.
250 : */
251 :
252 0 : css::uno::Sequence< css::uno::Type > SAL_CALL BackingComp::getTypes()
253 : throw(css::uno::RuntimeException, std::exception)
254 : {
255 : static ::cppu::OTypeCollection* pTypeCollection = NULL;
256 0 : if (!pTypeCollection)
257 : {
258 : /* GLOBAL SAFE { */
259 0 : ::osl::MutexGuard aGlobalLock(::osl::Mutex::getGlobalMutex());
260 : // Control these pointer again ... it can be, that another instance will be faster then this one!
261 0 : if (!pTypeCollection)
262 : {
263 : /* LOCAL SAFE { */
264 0 : SolarMutexGuard aGuard;
265 0 : css::uno::Reference< css::lang::XTypeProvider > xProvider(m_xWindow, css::uno::UNO_QUERY);
266 :
267 0 : css::uno::Sequence< css::uno::Type > lWindowTypes;
268 0 : if (xProvider.is())
269 0 : lWindowTypes = xProvider->getTypes();
270 :
271 : static ::cppu::OTypeCollection aTypeCollection(
272 0 : cppu::UnoType<css::lang::XInitialization>::get(),
273 0 : cppu::UnoType<css::lang::XTypeProvider>::get(),
274 0 : cppu::UnoType<css::lang::XServiceInfo>::get(),
275 0 : cppu::UnoType<css::frame::XController>::get(),
276 0 : cppu::UnoType<css::lang::XComponent>::get(),
277 0 : cppu::UnoType<css::frame::XDispatchProvider>::get(),
278 0 : cppu::UnoType<css::frame::XDispatch>::get(),
279 0 : lWindowTypes);
280 :
281 0 : pTypeCollection = &aTypeCollection;
282 : /* } LOCAL SAFE */
283 0 : }
284 : /* } GLOBAL SAFE */
285 : }
286 0 : return pTypeCollection->getTypes();
287 : }
288 :
289 :
290 :
291 : /** create one unique Id for all instances of this class.
292 :
293 : Optimize this method
294 : We initialize a static variable only one time. And we don't must use a mutex at every call!
295 : For the first call; pID is NULL - for the second call pID is different from NULL!
296 :
297 : @return A byte array, which represent the unique id.
298 : */
299 :
300 0 : css::uno::Sequence< sal_Int8 > SAL_CALL BackingComp::getImplementationId()
301 : throw(css::uno::RuntimeException, std::exception)
302 : {
303 0 : return css::uno::Sequence<sal_Int8>();
304 : }
305 :
306 1 : OUString SAL_CALL BackingComp::getImplementationName()
307 : throw(css::uno::RuntimeException, std::exception)
308 : {
309 1 : return OUString("com.sun.star.comp.sfx2.BackingComp");
310 : }
311 :
312 161 : sal_Bool SAL_CALL BackingComp::supportsService( /*IN*/ const OUString& sServiceName )
313 : throw(css::uno::RuntimeException, std::exception)
314 : {
315 161 : return cppu::supportsService(this, sServiceName);
316 : }
317 :
318 162 : css::uno::Sequence< OUString > SAL_CALL BackingComp::getSupportedServiceNames()
319 : throw(css::uno::RuntimeException, std::exception)
320 : {
321 162 : css::uno::Sequence< OUString > lNames(2);
322 162 : lNames[0] = "com.sun.star.frame.StartModule";
323 162 : lNames[1] = "com.sun.star.frame.ProtocolHandler";
324 162 : return lNames;
325 : }
326 :
327 :
328 : /**
329 : attach this component to a target frame.
330 :
331 : We have 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 1 : 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 1 : SolarMutexGuard aGuard;
386 :
387 : // check some required states
388 1 : if (m_xFrame.is())
389 : throw css::uno::RuntimeException(
390 : OUString("already attached"),
391 0 : static_cast< ::cppu::OWeakObject* >(this));
392 :
393 1 : if (!xFrame.is())
394 : throw css::uno::RuntimeException(
395 : OUString("invalid frame reference"),
396 0 : static_cast< ::cppu::OWeakObject* >(this));
397 :
398 1 : if (!m_xWindow.is())
399 1 : return; // disposed
400 :
401 : // safe the frame reference
402 1 : m_xFrame = xFrame;
403 :
404 : // initialize the component and its parent window
405 2 : css::uno::Reference< css::awt::XWindow > xParentWindow = xFrame->getContainerWindow();
406 2 : VclPtr< WorkWindow > pParent = static_cast<WorkWindow*>(VCLUnoHelper::GetWindow(xParentWindow).get());
407 2 : VclPtr< vcl::Window > pWindow = VCLUnoHelper::GetWindow(m_xWindow);
408 :
409 : // disable full screen mode of the frame!
410 1 : if (pParent && pParent->IsFullScreenMode())
411 : {
412 0 : pParent->ShowFullScreenMode(false);
413 0 : pParent->SetMenuBarMode(MenuBarMode::Normal);
414 : }
415 :
416 : // create the menu bar for the backing component
417 2 : css::uno::Reference< css::beans::XPropertySet > xPropSet(m_xFrame, css::uno::UNO_QUERY_THROW);
418 2 : css::uno::Reference< css::frame::XLayoutManager > xLayoutManager;
419 1 : xPropSet->getPropertyValue(FRAME_PROPNAME_LAYOUTMANAGER) >>= xLayoutManager;
420 1 : if (xLayoutManager.is())
421 : {
422 1 : xLayoutManager->lock();
423 1 : xLayoutManager->createElement("private:resource/menubar/menubar");
424 1 : xLayoutManager->unlock();
425 : }
426 :
427 1 : if (pWindow)
428 : {
429 : // set help ID for our canvas
430 1 : pWindow->SetHelpId(HID_BACKINGWINDOW);
431 : }
432 :
433 : // inform BackingWindow about frame
434 1 : BackingWindow* pBack = dynamic_cast<BackingWindow*>(pWindow.get());
435 1 : if( pBack )
436 1 : pBack->setOwningFrame( m_xFrame );
437 :
438 : // Set a minimum size for Start Center
439 1 : if( pParent && pBack )
440 : {
441 1 : long nMenuHeight = 0;
442 1 : vcl::Window* pMenu = pParent->GetWindow(GetWindowType::Next);
443 1 : if( pMenu )
444 1 : nMenuHeight = pMenu->GetSizePixel().Height();
445 :
446 1 : pParent->SetMinOutputSizePixel(
447 : Size(
448 1 : pBack->get_width_request(),
449 3 : pBack->get_height_request() + nMenuHeight));
450 1 : }
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/> every time.
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 36 : css::uno::Reference< css::frame::XModel > SAL_CALL BackingComp::getModel()
482 : throw (css::uno::RuntimeException, std::exception)
483 : {
484 36 : 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 1 : sal_Bool SAL_CALL BackingComp::suspend( /*IN*/ sal_Bool )
548 : throw (css::uno::RuntimeException, std::exception)
549 : {
550 : /* FIXME ... implemented by using default :-( */
551 1 : 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 isn't necessary here. The broadcaster do it automatically.
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 2 : void SAL_CALL BackingComp::dispose()
601 : throw(css::uno::RuntimeException, std::exception)
602 : {
603 : /* SAFE { */
604 2 : SolarMutexGuard aGuard;
605 :
606 : // kill the menu
607 4 : css::util::URL aURL;
608 2 : aURL.Complete = ".uno:close";
609 4 : css::uno::Reference< css::util::XURLTransformer > xParser = css::util::URLTransformer::create(m_xContext);
610 2 : if (xParser.is())
611 2 : xParser->parseStrict(aURL);
612 :
613 4 : css::uno::Reference< css::frame::XDispatchProvider > xProvider(m_xFrame, css::uno::UNO_QUERY);
614 2 : if (xProvider.is())
615 : {
616 1 : css::uno::Reference< css::frame::XDispatch > xDispatch = xProvider->queryDispatch(aURL, SPECIALTARGET_MENUBAR, 0);
617 1 : if (xDispatch.is())
618 1 : xDispatch->dispatch(aURL, css::uno::Sequence< css::beans::PropertyValue>());
619 : }
620 :
621 : // stop listening at the window
622 2 : if (m_xWindow.is())
623 : {
624 1 : css::uno::Reference< css::lang::XComponent > xBroadcaster(m_xWindow, css::uno::UNO_QUERY);
625 1 : if (xBroadcaster.is())
626 : {
627 1 : css::uno::Reference< css::lang::XEventListener > xEventThis(static_cast< ::cppu::OWeakObject* >(this), css::uno::UNO_QUERY);
628 1 : xBroadcaster->removeEventListener(xEventThis);
629 : }
630 2 : css::uno::Reference< css::awt::XKeyListener > xKeyThis(static_cast< ::cppu::OWeakObject* >(this), css::uno::UNO_QUERY);
631 1 : m_xWindow->removeKeyListener(xKeyThis);
632 2 : m_xWindow = css::uno::Reference< css::awt::XWindow >();
633 : }
634 :
635 : // forget all other used references
636 2 : m_xFrame.clear();
637 4 : m_xContext.clear();
638 :
639 : /* } SAFE */
640 2 : }
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 1 : 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 1 : SolarMutexGuard aGuard;
702 :
703 1 : if (m_xWindow.is())
704 : throw css::uno::Exception(
705 : OUString("already initialized"),
706 0 : static_cast< ::cppu::OWeakObject* >(this));
707 :
708 2 : css::uno::Reference< css::awt::XWindow > xParentWindow;
709 1 : if (
710 2 : (lArgs.getLength()!=1 ) ||
711 2 : (!(lArgs[0] >>= xParentWindow)) ||
712 1 : (!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 1 : vcl::Window* pParent = VCLUnoHelper::GetWindow(xParentWindow);
722 2 : VclPtr<vcl::Window> pWindow = VclPtr<BackingWindow>::Create(pParent);
723 1 : m_xWindow = VCLUnoHelper::GetInterface(pWindow);
724 :
725 1 : 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 2 : css::uno::Reference< css::lang::XComponent > xBroadcaster(m_xWindow, css::uno::UNO_QUERY);
733 1 : if (xBroadcaster.is())
734 1 : xBroadcaster->addEventListener(static_cast< css::lang::XEventListener* >(this));
735 :
736 2 : m_xWindow->setVisible(sal_True);
737 :
738 : /* } SAFE */
739 1 : }
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 : vcl::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 : VclPtr< WorkWindow > pParent = static_cast<WorkWindow*>(VCLUnoHelper::GetWindow(xParentWindow).get());
804 0 : if( pParent )
805 : {
806 0 : pParent->SetMinOutputSizePixel( Size(
807 0 : 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 2 : com_sun_star_comp_sfx2_BackingComp_get_implementation(
826 : css::uno::XComponentContext *context,
827 : css::uno::Sequence<css::uno::Any> const &)
828 : {
829 2 : return cppu::acquire(new BackingComp(context));
830 648 : }
831 :
832 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|