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