1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
20 #ifndef __FRAMEWORK_SERVICES_DESKTOP_HXX_
21 #define __FRAMEWORK_SERVICES_DESKTOP_HXX_
23 #include <classes/framecontainer.hxx>
24 #include <threadhelp/threadhelpbase.hxx>
25 #include <helper/oframes.hxx>
26 #include <macros/generic.hxx>
27 #include <macros/debug.hxx>
28 #include <macros/xinterface.hxx>
29 #include <macros/xtypeprovider.hxx>
30 #include <macros/xserviceinfo.hxx>
32 #include <com/sun/star/frame/XUntitledNumbers.hpp>
34 #include <com/sun/star/frame/XController.hpp>
35 #include <com/sun/star/frame/XDesktop2.hpp>
36 #include <com/sun/star/frame/WindowArrange.hpp>
37 #include <com/sun/star/frame/TerminationVetoException.hpp>
38 #include <com/sun/star/frame/XTerminateListener.hpp>
39 #include <com/sun/star/frame/XWindowArranger.hpp>
40 #include <com/sun/star/frame/XTask.hpp>
41 #include <com/sun/star/frame/XStorable.hpp>
42 #include <com/sun/star/frame/XModel.hpp>
43 #include <com/sun/star/frame/XFramesSupplier.hpp>
44 #include <com/sun/star/frame/XFrames.hpp>
45 #include <com/sun/star/lang/XServiceName.hpp>
46 #include <com/sun/star/frame/XDispatchProvider.hpp>
47 #include <com/sun/star/frame/XDispatchProviderInterception.hpp>
48 #include <com/sun/star/frame/XComponentLoader.hpp>
49 #include <com/sun/star/frame/FrameAction.hpp>
50 #include <com/sun/star/frame/XTasksSupplier.hpp>
51 #include <com/sun/star/container/XEnumerationAccess.hpp>
52 #include <com/sun/star/lang/Locale.hpp>
53 #include <com/sun/star/frame/XDispatchResultListener.hpp>
54 #include <com/sun/star/lang/XEventListener.hpp>
55 #include <com/sun/star/frame/FeatureStateEvent.hpp>
56 #include <com/sun/star/task/XInteractionHandler.hpp>
57 #include <com/sun/star/frame/XDispatchRecorderSupplier.hpp>
59 #include <unotools/cmdoptions.hxx>
60 #include <cppuhelper/propshlp.hxx>
61 #include <cppuhelper/interfacecontainer.hxx>
62 #include <cppuhelper/weak.hxx>
64 #include <comphelper/numberedcollection.hxx>
76 /*-************************************************************************************************************//**
77 @short implement the topframe of frame tree
78 @descr This is the root of the frame tree. The desktop has no window, is not visible but he is the logical
79 "masternode" to build the hierarchy.
81 @implements XInterface
94 XDispatchResultListener
103 @devstatus ready to use
105 *//*-*************************************************************************************************************/
106 class Desktop
: // interfaces
107 public css::lang::XTypeProvider
,
108 public css::lang::XServiceInfo
,
109 public css::frame::XDesktop2
,
110 public css::frame::XTasksSupplier
,
111 public css::frame::XDispatchResultListener
, // => XEventListener
112 public css::task::XInteractionHandler
,
113 public css::frame::XUntitledNumbers
,
115 // Order is necessary for right initialization!
116 private ThreadHelpBase
,
117 private TransactionBase
,
118 public ::cppu::OBroadcastHelper
,
119 public ::cppu::OPropertySetHelper
,
120 public ::cppu::OWeakObject
122 // internal used types, const etcpp.
125 //---------------------------------------------------------------------
126 /** used temporary to know which listener was already called or not. */
127 typedef ::std::vector
< css::uno::Reference
< css::frame::XTerminateListener
> > TTerminateListenerList
;
132 // constructor / destructor
133 Desktop( const css::uno::Reference
< css::lang::XMultiServiceFactory
>& xFactory
);
136 // XInterface, XTypeProvider, XServiceInfo
137 FWK_DECLARE_XINTERFACE
138 FWK_DECLARE_XTYPEPROVIDER
141 //---------------------------------------------------------------------
145 @short try to shutdown these desktop environment.
147 @descr Will try to close all frames. If at least one frame could
148 not be closed successfully termination will be stopped.
150 Registered termination listener will be taken into account
151 also. As special feature some of our registered listener
152 are well known by it's UNO implementation name. They are handled
153 different to all other listener.
155 Btw: Desktop.terminate() was designed in the past to be used
156 within an UI based envrionment. So it's allowed e.g. to
157 call XController.suspend() here. If UI isnt an option ... please
158 use XCloseable.close() at these desktop implementation.
159 ... if it will be supported in the future .-))
161 @seealso XTerminateListener
162 @seealso XTerminateListener2
164 @return true if all open frames could be closed and no listener throwed
165 a veto exception; false otherwise.
167 @onerror False will be returned.
170 virtual ::sal_Bool SAL_CALL
terminate()
171 throw( css::uno::RuntimeException
);
173 //---------------------------------------------------------------------
177 @short add a listener for termination events
179 @descr Additional to adding normal listener these method was implemented special.
180 Every listener will be asked for it's uno implementation name.
181 Some of them are well known ... and the corresponding listener wont be added
182 to the container of "normal listener". Those listener will be set as special
184 see e.g. member m_xSfxTerminator
189 the listener for registration.
193 virtual void SAL_CALL
addTerminateListener( const css::uno::Reference
< css::frame::XTerminateListener
>& xListener
)
194 throw( css::uno::RuntimeException
);
196 //---------------------------------------------------------------------
200 @short remove a listener from this container.
202 @descr Additional to removing normal listener these method was implemented special.
203 Every listener will be asked for it's uno implementation name.
204 Some of them are well known ... and the corresponding listener was set as special member.
205 Now those special member will be reseted also.
206 see e.g. member m_xSfxTerminator
211 the listener for deregistration.
215 virtual void SAL_CALL
removeTerminateListener( const css::uno::Reference
< css::frame::XTerminateListener
>& xListener
)
216 throw( css::uno::RuntimeException
);
218 virtual css::uno::Reference
< css::container::XEnumerationAccess
> SAL_CALL
getComponents ( ) throw( css::uno::RuntimeException
);
219 virtual css::uno::Reference
< css::lang::XComponent
> SAL_CALL
getCurrentComponent ( ) throw( css::uno::RuntimeException
);
220 virtual css::uno::Reference
< css::frame::XFrame
> SAL_CALL
getCurrentFrame ( ) throw( css::uno::RuntimeException
);
223 virtual css::uno::Reference
< css::lang::XComponent
> SAL_CALL
loadComponentFromURL ( const OUString
& sURL
,
224 const OUString
& sTargetFrameName
,
225 sal_Int32 nSearchFlags
,
226 const css::uno::Sequence
< css::beans::PropertyValue
>& lArguments
) throw( css::io::IOException
,
227 css::lang::IllegalArgumentException
,
228 css::uno::RuntimeException
);
231 virtual css::uno::Reference
< css::container::XEnumerationAccess
> SAL_CALL
getTasks ( ) throw( css::uno::RuntimeException
);
232 virtual css::uno::Reference
< css::frame::XTask
> SAL_CALL
getActiveTask ( ) throw( css::uno::RuntimeException
);
235 virtual css::uno::Reference
< css::frame::XDispatch
> SAL_CALL
queryDispatch ( const css::util::URL
& aURL
,
236 const OUString
& sTargetFrameName
,
237 sal_Int32 nSearchFlags
) throw( css::uno::RuntimeException
);
238 virtual css::uno::Sequence
< css::uno::Reference
< css::frame::XDispatch
> > SAL_CALL
queryDispatches ( const css::uno::Sequence
< css::frame::DispatchDescriptor
>& lQueries
) throw( css::uno::RuntimeException
);
240 // XDispatchProviderInterception
241 virtual void SAL_CALL
registerDispatchProviderInterceptor( const css::uno::Reference
< css::frame::XDispatchProviderInterceptor
>& xInterceptor
) throw( css::uno::RuntimeException
);
242 virtual void SAL_CALL
releaseDispatchProviderInterceptor ( const css::uno::Reference
< css::frame::XDispatchProviderInterceptor
>& xInterceptor
) throw( css::uno::RuntimeException
);
245 virtual css::uno::Reference
< css::frame::XFrames
> SAL_CALL
getFrames ( ) throw( css::uno::RuntimeException
);
246 virtual css::uno::Reference
< css::frame::XFrame
> SAL_CALL
getActiveFrame ( ) throw( css::uno::RuntimeException
);
247 virtual void SAL_CALL
setActiveFrame ( const css::uno::Reference
< css::frame::XFrame
>& xFrame
) throw( css::uno::RuntimeException
);
250 // Attention: findFrame() is implemented only! Other methods make no sense for our desktop!
251 virtual css::uno::Reference
< css::frame::XFrame
> SAL_CALL
findFrame ( const OUString
& sTargetFrameName
,
252 sal_Int32 nSearchFlags
) throw( css::uno::RuntimeException
);
253 virtual void SAL_CALL
initialize ( const css::uno::Reference
< css::awt::XWindow
>& xWindow
) throw( css::uno::RuntimeException
);
254 virtual css::uno::Reference
< css::awt::XWindow
> SAL_CALL
getContainerWindow ( ) throw( css::uno::RuntimeException
);
255 virtual void SAL_CALL
setCreator ( const css::uno::Reference
< css::frame::XFramesSupplier
>& xCreator
) throw( css::uno::RuntimeException
);
256 virtual css::uno::Reference
< css::frame::XFramesSupplier
> SAL_CALL
getCreator ( ) throw( css::uno::RuntimeException
);
257 virtual OUString SAL_CALL
getName ( ) throw( css::uno::RuntimeException
);
258 virtual void SAL_CALL
setName ( const OUString
& sName
) throw( css::uno::RuntimeException
);
259 virtual sal_Bool SAL_CALL
isTop ( ) throw( css::uno::RuntimeException
);
260 virtual void SAL_CALL
activate ( ) throw( css::uno::RuntimeException
);
261 virtual void SAL_CALL
deactivate ( ) throw( css::uno::RuntimeException
);
262 virtual sal_Bool SAL_CALL
isActive ( ) throw( css::uno::RuntimeException
);
263 virtual sal_Bool SAL_CALL
setComponent ( const css::uno::Reference
< css::awt::XWindow
>& xComponentWindow
,
264 const css::uno::Reference
< css::frame::XController
>& xController
) throw( css::uno::RuntimeException
);
265 virtual css::uno::Reference
< css::awt::XWindow
> SAL_CALL
getComponentWindow ( ) throw( css::uno::RuntimeException
);
266 virtual css::uno::Reference
< css::frame::XController
> SAL_CALL
getController ( ) throw( css::uno::RuntimeException
);
267 virtual void SAL_CALL
contextChanged ( ) throw( css::uno::RuntimeException
);
268 virtual void SAL_CALL
addFrameActionListener ( const css::uno::Reference
< css::frame::XFrameActionListener
>& xListener
) throw( css::uno::RuntimeException
);
269 virtual void SAL_CALL
removeFrameActionListener ( const css::uno::Reference
< css::frame::XFrameActionListener
>& xListener
) throw( css::uno::RuntimeException
);
272 using cppu::OPropertySetHelper::disposing
;
273 virtual void SAL_CALL
dispose ( ) throw( css::uno::RuntimeException
);
274 virtual void SAL_CALL
addEventListener ( const css::uno::Reference
< css::lang::XEventListener
>& xListener
) throw( css::uno::RuntimeException
);
275 virtual void SAL_CALL
removeEventListener ( const css::uno::Reference
< css::lang::XEventListener
>& xListener
) throw( css::uno::RuntimeException
);
277 // XDispatchResultListener
278 virtual void SAL_CALL
dispatchFinished ( const css::frame::DispatchResultEvent
& aEvent
) throw( css::uno::RuntimeException
);
281 virtual void SAL_CALL
disposing ( const css::lang::EventObject
& aSource
) throw( css::uno::RuntimeException
);
283 // XInteractionHandler
284 virtual void SAL_CALL
handle ( const css::uno::Reference
< css::task::XInteractionRequest
>& xRequest
) throw( css::uno::RuntimeException
);
286 // css.frame.XUntitledNumbers
287 virtual ::sal_Int32 SAL_CALL
leaseNumber( const css::uno::Reference
< css::uno::XInterface
>& xComponent
)
288 throw (css::lang::IllegalArgumentException
,
289 css::uno::RuntimeException
);
291 // css.frame.XUntitledNumbers
292 virtual void SAL_CALL
releaseNumber( ::sal_Int32 nNumber
)
293 throw (css::lang::IllegalArgumentException
,
294 css::uno::RuntimeException
);
296 // css.frame.XUntitledNumbers
297 virtual void SAL_CALL
releaseNumberForComponent( const css::uno::Reference
< css::uno::XInterface
>& xComponent
)
298 throw (css::lang::IllegalArgumentException
,
299 css::uno::RuntimeException
);
301 // css.frame.XUntitledNumbers
302 virtual OUString SAL_CALL
getUntitledPrefix()
303 throw (css::uno::RuntimeException
);
305 // we need this wrapped terminate()-call to terminate even the QuickStarter
306 // non-virtual and non-UNO for now
307 bool SAL_CALL
terminateQuickstarterToo()
308 throw( css::uno::RuntimeException
);
309 //-------------------------------------------------------------------------------------------------------------
311 //-------------------------------------------------------------------------------------------------------------
314 // OPropertySetHelper
315 virtual sal_Bool SAL_CALL
convertFastPropertyValue ( css::uno::Any
& aConvertedValue
,
316 css::uno::Any
& aOldValue
,
318 const css::uno::Any
& aValue
) throw( css::lang::IllegalArgumentException
);
319 virtual void SAL_CALL
setFastPropertyValue_NoBroadcast( sal_Int32 nHandle
,
320 const css::uno::Any
& aValue
) throw( css::uno::Exception
);
321 using cppu::OPropertySetHelper::getFastPropertyValue
;
322 virtual void SAL_CALL
getFastPropertyValue ( css::uno::Any
& aValue
,
323 sal_Int32 nHandle
) const;
324 virtual ::cppu::IPropertyArrayHelper
& SAL_CALL
getInfoHelper ( );
325 virtual css::uno::Reference
< css::beans::XPropertySetInfo
> SAL_CALL
getPropertySetInfo ( ) throw (css::uno::RuntimeException
);
327 //-------------------------------------------------------------------------------------------------------------
329 //-------------------------------------------------------------------------------------------------------------
332 css::uno::Reference
< css::lang::XComponent
> impl_getFrameComponent ( const css::uno::Reference
< css::frame::XFrame
>& xFrame
) const;
333 static const css::uno::Sequence
< css::beans::Property
> impl_getStaticPropertyDescriptor( );
335 //---------------------------------------------------------------------
336 /** calls queryTermination() on every registered termination listener.
338 * Note: Only normal termination listener (registered in list m_aListenerContainer
339 * will be recognized here. Special listener like quick starter, pipe or others
340 * has to be handled explicitly !
342 * @param [out] lCalledListener
343 * every called listener will be returned here.
344 * Those list will be used to informa all called listener
345 * about cancel this termination request.
348 * will be true if at least one listener throwed a veto exception;
351 * @see impl_sendCancelTerminationEvent()
353 void impl_sendQueryTerminationEvent(TTerminateListenerList
& lCalledListener
,
356 //---------------------------------------------------------------------
357 /** calls cancelTermination() on every termination listener
358 * where queryTermination() was called before.
360 * Note: Only normal termination listener (registered in list m_aListenerContainer
361 * will be recognized here. Special listener like quick starter, pipe or others
362 * has to be handled explicitly !
364 * @param [in] lCalledListener
365 * every listener in this list was called within its method
366 * queryTermination() before.
368 * @see impl_sendQueryTerminationEvent()
370 void impl_sendCancelTerminationEvent(const TTerminateListenerList
& lCalledListener
);
372 //---------------------------------------------------------------------
373 /** calls notifyTermination() on every registered termination listener.
375 * Note: Only normal termination listener (registered in list m_aListenerContainer
376 * will be recognized here. Special listener like quick starter, pipe or others
377 * has to be handled explicitly !
379 void impl_sendNotifyTerminationEvent();
381 //---------------------------------------------------------------------
382 /** try to close all open frames.
384 * Iterates over all child frames and try to close them.
385 * Given parameter bAllowUI enable/disable showing any UI
386 * (which mostly occure on calling XController->suspend()).
388 * These method doesnt stop if one frame could not be closed.
389 * It will ignore such frames and try all other ones.
390 * But it returns false in such case - true otherwise.
393 * enable/disable showing of UI.
395 * @return true if all frames could be closed; false otherwise.
397 ::sal_Bool
impl_closeFrames(::sal_Bool bAllowUI
);
399 //-------------------------------------------------------------------------------------------------------------
401 // (should be private everytime!)
402 //-------------------------------------------------------------------------------------------------------------
403 #ifdef ENABLE_ASSERTIONS
406 static sal_Bool
implcp_ctor ( const css::uno::Reference
< css::lang::XMultiServiceFactory
>& xFactory
);
407 static sal_Bool
implcp_addEventListener ( const css::uno::Reference
< css::lang::XEventListener
>& xListener
);
408 static sal_Bool
implcp_removeEventListener ( const css::uno::Reference
< css::lang::XEventListener
>& xListener
);
410 sal_Bool m_bIsTerminated
; /// check flag to protect us against dispose before terminate!
411 /// see dispose() for further information!
413 #endif // #ifdef ENABLE_ASSERTIONS
415 //-------------------------------------------------------------------------------------------------------------
417 // (should be private everytime!)
418 //-------------------------------------------------------------------------------------------------------------
421 css::uno::Reference
< css::lang::XMultiServiceFactory
> m_xFactory
; /// reference to factory, which has create this instance
422 FrameContainer m_aChildTaskContainer
; /// array of child tasks (children of desktop are tasks; and tasks are also frames - But pure frames are not accepted!)
423 ::cppu::OMultiTypeInterfaceContainerHelper m_aListenerContainer
; /// container for ALL Listener
424 css::uno::Reference
< css::frame::XFrames
> m_xFramesHelper
; /// helper for XFrames, XIndexAccess, XElementAccess and implementation of a childcontainer!
425 css::uno::Reference
< css::frame::XDispatchProvider
> m_xDispatchHelper
; /// helper to dispatch something for new tasks, created by "_blank"!
426 ELoadState m_eLoadState
; /// hold information about state of asynchron loading of component for loadComponentFromURL()!
427 css::uno::Reference
< css::frame::XFrame
> m_xLastFrame
; /// last target of "loadComponentFromURL()"!
428 css::uno::Any m_aInteractionRequest
;
429 sal_Bool m_bSuspendQuickstartVeto
; /// don't ask quickstart for a veto
430 SvtCommandOptions m_aCommandOptions
; /// ref counted class to support disabling commands defined by configuration file
433 css::uno::Reference
< css::frame::XDispatchRecorderSupplier
> m_xDispatchRecorderSupplier
;
435 //---------------------------------------------------------------------
436 /** special terminate listener to close pipe and block external requests
437 * during/after termination process is/was running
439 css::uno::Reference
< css::frame::XTerminateListener
> m_xPipeTerminator
;
441 //---------------------------------------------------------------------
442 /** special terminate listener shown inside system tray (quick starter)
443 * Will hinder the office on shutdown ... but wish to allow closing
444 * of open documents. And because thats different to a normal terminate listener
445 * it has to be handled special .-)
447 css::uno::Reference
< css::frame::XTerminateListener
> m_xQuickLauncher
;
449 //---------------------------------------------------------------------
450 /** special terminate listener which loads images asynchronous for current open documents.
451 * Because internaly it uses blocking system APIs ... it cant be guaranteed that
452 * running jobs can be cancelled successfully if the corressponding document will be closed ...
453 * it will not hinder those documents on closing. Instead it let all jobs running ...
454 * but at least on terminate we have to wait for all those blocked requests.
455 * So these implementation must be a special terminate listener too .-(
457 css::uno::Reference
< css::frame::XTerminateListener
> m_xSWThreadManager
;
459 //---------------------------------------------------------------------
460 /** special terminate listener shuting down the SfxApplication.
461 * Because these desktop instance closes documents and informs listener
462 * only ... it does not realy shutdown the whole application.
464 * Btw: That wouldnt be possible by design ... because Desktop.terminate()
465 * has to return a boolean value about success ... it cant realy shutdown the
468 * So we uses a trick: A special listener (exactly these one here) listen for notifyTermination()
469 * and shutdown the process asynchronous. But desktop has to make this special
470 * notification as realy last one ... Otherwhise it can happen that asynchronous
471 * shutdown will be faster then all other code around Desktop.terminate() .-))
473 css::uno::Reference
< css::frame::XTerminateListener
> m_xSfxTerminator
;
475 css::uno::Reference
< css::frame::XUntitledNumbers
> m_xTitleNumberGenerator
;
479 } // namespace framework
481 #endif // #ifndef __FRAMEWORK_SERVICES_DESKTOP_HXX_
483 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */