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