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