Coverage Report

Created: 2025-11-16 09:57

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libreoffice/include/framework/desktop.hxx
Line
Count
Source
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
#pragma once
21
22
#include <sal/config.h>
23
24
#include <memory>
25
#include <vector>
26
27
#include "framecontainer.hxx"
28
#include "fwkdllapi.h"
29
#include "transactionmanager.hxx"
30
31
#include <com/sun/star/frame/XUntitledNumbers.hpp>
32
#include <com/sun/star/frame/XDesktop2.hpp>
33
#include <com/sun/star/frame/XTerminateListener.hpp>
34
#include <com/sun/star/lang/XServiceInfo.hpp>
35
#include <com/sun/star/frame/XTasksSupplier.hpp>
36
#include <com/sun/star/frame/XDispatchResultListener.hpp>
37
#include <com/sun/star/lang/XComponent.hpp>
38
#include <com/sun/star/task/XInteractionHandler.hpp>
39
#include <com/sun/star/frame/XDispatchRecorderSupplier.hpp>
40
#include <com/sun/star/uno/XComponentContext.hpp>
41
42
#include <comphelper/multicontainer2.hxx>
43
#include <cppuhelper/basemutex.hxx>
44
#include <cppuhelper/compbase.hxx>
45
#include <cppuhelper/propshlp.hxx>
46
#include <rtl/ref.hxx>
47
#include <unotools/cmdoptions.hxx>
48
49
namespace comphelper { class NumberedCollection; }
50
51
namespace framework{
52
53
class InterceptionHelper;
54
class OFrames;
55
56
enum ELoadState
57
{
58
    E_NOTSET      ,
59
    E_SUCCESSFUL  ,
60
    E_FAILED      ,
61
    E_INTERACTION
62
};
63
64
/*-************************************************************************************************************
65
    @short      implement the topframe of frame tree
66
    @descr      This is the root of the frame tree. The desktop has no window, is not visible but he is the logical
67
                "masternode" to build the hierarchy.
68
69
    @implements XInterface
70
                XTypeProvider
71
                XServiceInfo
72
                XDesktop
73
                XComponentLoader
74
                XTasksSupplier
75
                XDispatchProvider
76
                XFramesSupplier
77
                XFrame
78
                XComponent
79
                XPropertySet
80
                XFastPropertySet
81
                XMultiPropertySet
82
                XDispatchResultListener
83
                XEventListener
84
                XInteractionHandler
85
86
    @devstatus  ready to use
87
    @threadsafe yes
88
*//*-*************************************************************************************************************/
89
typedef cppu::WeakComponentImplHelper<
90
           css::lang::XServiceInfo              ,
91
           css::frame::XDesktop2                ,
92
           css::frame::XTasksSupplier           ,
93
           css::frame::XDispatchResultListener  ,   // => XEventListener
94
           css::task::XInteractionHandler       ,
95
           css::frame::XUntitledNumbers > Desktop_BASE;
96
97
class FWK_DLLPUBLIC Desktop final : private cppu::BaseMutex,
98
                public Desktop_BASE,
99
                public cppu::OPropertySetHelper
100
{
101
    // internal used types, const etcpp.
102
    private:
103
104
        /** used temporary to know which listener was already called or not. */
105
        typedef ::std::vector< css::uno::Reference< css::frame::XTerminateListener > > TTerminateListenerList;
106
107
    // public methods
108
    public:
109
110
        //  constructor / destructor
111
                 Desktop( css::uno::Reference< css::uno::XComponentContext >  xContext );
112
        virtual ~Desktop(                                                                    ) override;
113
114
        void constructorInit();
115
116
        //  XServiceInfo
117
        virtual OUString SAL_CALL getImplementationName() override;
118
119
        virtual sal_Bool SAL_CALL supportsService(OUString const & ServiceName) override;
120
121
        virtual css::uno::Sequence<OUString> SAL_CALL getSupportedServiceNames() override;
122
123
        // XInterface
124
        virtual void SAL_CALL acquire() noexcept override
125
20.7M
            { OWeakObject::acquire(); }
126
        virtual void SAL_CALL release() noexcept override
127
20.7M
            { OWeakObject::release(); }
128
        virtual css::uno::Any SAL_CALL queryInterface( const css::uno::Type& type) override;
129
130
        // XTypeProvider
131
        virtual css::uno::Sequence< css::uno::Type > SAL_CALL getTypes(  ) override;
132
133
        /**
134
            @interface  XDesktop
135
136
            @short      try to shutdown these desktop environment.
137
138
            @descr      Will try to close all frames. If at least one frame could
139
                        not be closed successfully termination will be stopped.
140
141
                        Registered termination listener will be taken into account
142
                        also. As special feature some of our registered listener
143
                        are well known by its UNO implementation name. They are handled
144
                        different to all other listener.
145
146
                        Btw: Desktop.terminate() was designed in the past to be used
147
                        within an UI based environment. So it's allowed e.g. to
148
                        call XController.suspend() here. If UI isn't an option ... please
149
                        use XCloseable.close() at these desktop implementation.
150
                        ... if it will be supported in the future .-))
151
152
            @seealso    XTerminateListener
153
            @seealso    XTerminateListener2
154
155
            @return     true if all open frames could be closed and no listener threw
156
                        a veto exception; false otherwise.
157
158
            @onerror    False will be returned.
159
            @threadsafe yes
160
         */
161
        virtual sal_Bool SAL_CALL terminate() override;
162
163
        /**
164
            @interface  XDesktop
165
166
            @short      add a listener for termination events
167
168
            @descr      Additional to adding normal listener these method was implemented special.
169
                        Every listener will be asked for its uno implementation name.
170
                        Some of them are well known... and the corresponding listener won't be added
171
                        to the container of "normal listener". Those listener will be set as special
172
                        member.
173
                        see e.g. member m_xSfxTerminator
174
175
            @seealso    terminate()
176
177
            @param      xListener
178
                        the listener for registration.
179
180
            @threadsafe yes
181
         */
182
        virtual void SAL_CALL addTerminateListener( const css::uno::Reference< css::frame::XTerminateListener >& xListener ) override;
183
184
        /**
185
            @interface  XDesktop
186
187
            @short      remove a listener from this container.
188
189
            @descr      Additional to removing normal listener these method was implemented special.
190
                        Every listener will be asked for its uno implementation name.
191
                        Some of them are well known... and the corresponding listener was set as special member.
192
                        Now those special member will be reset also.
193
                        see e.g. member m_xSfxTerminator
194
195
            @seealso    terminate()
196
197
            @param      xListener
198
                        the listener for deregistration.
199
200
            @threadsafe yes
201
         */
202
        virtual void SAL_CALL removeTerminateListener( const css::uno::Reference< css::frame::XTerminateListener >& xListener ) override;
203
204
        virtual css::uno::Reference< css::container::XEnumerationAccess >           SAL_CALL getComponents              (                                                                                 ) override;
205
        virtual css::uno::Reference< css::lang::XComponent >                        SAL_CALL getCurrentComponent        (                                                                                 ) override;
206
        virtual css::uno::Reference< css::frame::XFrame >                           SAL_CALL getCurrentFrame            (                                                                                 ) override;
207
208
        //  XComponentLoader
209
        virtual css::uno::Reference< css::lang::XComponent >                        SAL_CALL loadComponentFromURL       ( const OUString&                                         sURL             ,
210
                                                                                                                          const OUString&                                         sTargetFrameName ,
211
                                                                                                                                sal_Int32                                                nSearchFlags     ,
212
                                                                                                                          const css::uno::Sequence< css::beans::PropertyValue >&         lArguments       ) override;
213
214
        //  XTasksSupplier
215
        virtual css::uno::Reference< css::container::XEnumerationAccess >           SAL_CALL getTasks                   (                                                                                 ) override;
216
        virtual css::uno::Reference< css::frame::XTask >                            SAL_CALL getActiveTask              (                                                                                 ) override;
217
218
        //  XDispatchProvider
219
        virtual css::uno::Reference< css::frame::XDispatch >                        SAL_CALL queryDispatch              ( const css::util::URL&                                          aURL             ,
220
                                                                                                                          const OUString&                                         sTargetFrameName ,
221
                                                                                                                                sal_Int32                                                nSearchFlags     ) override;
222
        virtual css::uno::Sequence< css::uno::Reference< css::frame::XDispatch > >  SAL_CALL queryDispatches            ( const css::uno::Sequence< css::frame::DispatchDescriptor >&    lQueries         ) override;
223
224
        // XDispatchProviderInterception
225
        virtual void                                                                SAL_CALL registerDispatchProviderInterceptor( const css::uno::Reference< css::frame::XDispatchProviderInterceptor >& xInterceptor) override;
226
        virtual void                                                                SAL_CALL releaseDispatchProviderInterceptor ( const css::uno::Reference< css::frame::XDispatchProviderInterceptor >& xInterceptor) override;
227
228
        //  XFramesSupplier
229
        virtual css::uno::Reference< css::frame::XFrames >                          SAL_CALL getFrames                  (                                                                                 ) override;
230
        virtual css::uno::Reference< css::frame::XFrame >                           SAL_CALL getActiveFrame             (                                                                                 ) override;
231
        virtual void                                                                SAL_CALL setActiveFrame             ( const css::uno::Reference< css::frame::XFrame >&               xFrame           ) override;
232
233
        //   XFrame
234
        //  Attention: findFrame() is implemented only! Other methods make no sense for our desktop!
235
        virtual css::uno::Reference< css::frame::XFrame >                           SAL_CALL findFrame                  ( const OUString&                                         sTargetFrameName ,
236
                                                                                                                                sal_Int32                                                nSearchFlags     ) override;
237
        virtual void                                                                SAL_CALL initialize                 ( const css::uno::Reference< css::awt::XWindow >&                xWindow          ) override;
238
        virtual css::uno::Reference< css::awt::XWindow >                            SAL_CALL getContainerWindow         (                                                                                 ) override;
239
        virtual void                                                                SAL_CALL setCreator                 ( const css::uno::Reference< css::frame::XFramesSupplier >&      xCreator         ) override;
240
        virtual css::uno::Reference< css::frame::XFramesSupplier >                  SAL_CALL getCreator                 (                                                                                 ) override;
241
        virtual OUString                                                     SAL_CALL getName                    (                                                                                 ) override;
242
        virtual void                                                                SAL_CALL setName                    ( const OUString&                                         sName            ) override;
243
        virtual sal_Bool                                                            SAL_CALL isTop                      (                                                                                 ) override;
244
        virtual void                                                                SAL_CALL activate                   (                                                                                 ) override;
245
        virtual void                                                                SAL_CALL deactivate                 (                                                                                 ) override;
246
        virtual sal_Bool                                                            SAL_CALL isActive                   (                                                                                 ) override;
247
        virtual sal_Bool                                                            SAL_CALL setComponent               ( const css::uno::Reference< css::awt::XWindow >&                xComponentWindow ,
248
                                                                                                                          const css::uno::Reference< css::frame::XController >&          xController      ) override;
249
        virtual css::uno::Reference< css::awt::XWindow >                            SAL_CALL getComponentWindow         (                                                                                 ) override;
250
        virtual css::uno::Reference< css::frame::XController >                      SAL_CALL getController              (                                                                                 ) override;
251
        virtual void                                                                SAL_CALL contextChanged             (                                                                                 ) override;
252
        virtual void                                                                SAL_CALL addFrameActionListener     ( const css::uno::Reference< css::frame::XFrameActionListener >& xListener        ) override;
253
        virtual void                                                                SAL_CALL removeFrameActionListener  ( const css::uno::Reference< css::frame::XFrameActionListener >& xListener        ) override;
254
255
        //   XComponent
256
        virtual void SAL_CALL disposing() override;
257
        virtual void                                                                SAL_CALL addEventListener           ( const css::uno::Reference< css::lang::XEventListener >&        xListener        ) override;
258
        virtual void                                                                SAL_CALL removeEventListener        ( const css::uno::Reference< css::lang::XEventListener >&        xListener        ) override;
259
260
        //   XDispatchResultListener
261
        virtual void SAL_CALL dispatchFinished      ( const css::frame::DispatchResultEvent&                    aEvent     ) override;
262
263
        //   XEventListener
264
        virtual void                                                                SAL_CALL disposing                  ( const css::lang::EventObject&                                  aSource          ) override;
265
266
        //   XInteractionHandler
267
        virtual void                                                                SAL_CALL handle                     ( const css::uno::Reference< css::task::XInteractionRequest >&   xRequest         ) override;
268
269
        // css.frame.XUntitledNumbers
270
        virtual ::sal_Int32 SAL_CALL leaseNumber( const css::uno::Reference< css::uno::XInterface >& xComponent ) override;
271
272
        // css.frame.XUntitledNumbers
273
        virtual void SAL_CALL releaseNumber( ::sal_Int32 nNumber ) override;
274
275
        // css.frame.XUntitledNumbers
276
        virtual void SAL_CALL releaseNumberForComponent( const css::uno::Reference< css::uno::XInterface >& xComponent ) override;
277
278
        // css.frame.XUntitledNumbers
279
        virtual OUString SAL_CALL getUntitledPrefix() override;
280
281
        // we need this wrapped terminate()-call to terminate even the QuickStarter
282
        // non-virtual and non-UNO for now
283
        /// @throws css::uno::RuntimeException
284
        bool terminateQuickstarterToo();
285
286
        void shutdown();
287
288
    private:
289
        //  OPropertySetHelper
290
        virtual sal_Bool                                            SAL_CALL convertFastPropertyValue        (       css::uno::Any&  aConvertedValue ,
291
                                                                                                                     css::uno::Any&  aOldValue       ,
292
                                                                                                                     sal_Int32       nHandle         ,
293
                                                                                                               const css::uno::Any&  aValue          ) override;
294
        virtual void                                                SAL_CALL setFastPropertyValue_NoBroadcast(       sal_Int32       nHandle         ,
295
                                                                                                               const css::uno::Any&  aValue          ) override;
296
        using cppu::OPropertySetHelper::getFastPropertyValue;
297
        virtual void                                                SAL_CALL getFastPropertyValue            (       css::uno::Any&  aValue          ,
298
                                                                                                                     sal_Int32       nHandle         ) const override;
299
        virtual ::cppu::IPropertyArrayHelper&                       SAL_CALL getInfoHelper                   (                                       ) override;
300
        virtual css::uno::Reference< css::beans::XPropertySetInfo > SAL_CALL getPropertySetInfo              (                                       ) override;
301
302
        css::uno::Reference< css::lang::XComponent >            impl_getFrameComponent          ( const css::uno::Reference< css::frame::XFrame >&  xFrame          ) const;
303
304
        /** calls queryTermination() on every registered termination listener.
305
         *
306
         *  Note: Only normal termination listener (registered in list m_aListenerContainer
307
         *        will be recognized here. Special listener like quick starter, pipe or others
308
         *        has to be handled explicitly !
309
         *
310
         *  @param  [out] lCalledListener
311
         *          every called listener will be returned here.
312
         *          Those list will be used to inform all called listener
313
         *          about cancel this termination request.
314
         *
315
         *  @return true if no one vetoed the termination.
316
         *
317
         *  @see    impl_sendCancelTerminationEvent()
318
         */
319
        bool impl_sendQueryTerminationEvent(TTerminateListenerList& lCalledListener);
320
321
        /** calls cancelTermination() on every termination listener
322
         *  where queryTermination() was called before.
323
         *
324
         *  Note: Only normal termination listener (registered in list m_aListenerContainer
325
         *        will be recognized here. Special listener like quick starter, pipe or others
326
         *        has to be handled explicitly !
327
         *
328
         *  @param  [in] lCalledListener
329
         *          every listener in this list was called within its method
330
         *          queryTermination() before.
331
         *
332
         *  @see    impl_sendQueryTerminationEvent()
333
         */
334
        void impl_sendCancelTerminationEvent(const TTerminateListenerList& lCalledListener);
335
336
        /** calls notifyTermination() on the clipboard listener
337
         *
338
         * The system clipboard may decide that it wants copies
339
         * in several formats of the clipboard content requiring
340
         * nearly all the services
341
         *
342
         */
343
        void impl_sendTerminateToClipboard();
344
345
        /** calls notifyTermination() on every registered termination listener.
346
         *
347
         *  Note: Only normal termination listener (registered in list m_aListenerContainer
348
         *        will be recognized here. Special listener like quick starter, pipe or others
349
         *        has to be handled explicitly !
350
         */
351
        void impl_sendNotifyTerminationEvent();
352
353
        /** try to close all open frames.
354
         *
355
         *  Iterates over all child frames and try to close them.
356
         *  Given parameter bAllowUI enable/disable showing any UI
357
         *  (which mostly occur on calling XController->suspend()).
358
         *
359
         *  This method doesn't stop if one frame could not be closed.
360
         *  It will ignore such frames and try all other ones.
361
         *  But it returns false in such case - true otherwise.
362
         *
363
         *  @param  bAllowUI
364
         *          enable/disable showing of UI.
365
         *
366
         *  @return true if all frames could be closed; false otherwise.
367
         */
368
        bool impl_closeFrames(bool bAllowUI);
369
370
    private:
371
372
        mutable TransactionManager    m_aTransactionManager;
373
374
        /** check flag to protect against multiple terminate runs
375
          */
376
        bool m_bIsTerminated;
377
378
        /** check flag to protect us against dispose before terminate!
379
          *   see dispose() for further information!
380
          */
381
        bool m_bIsShutdown;
382
383
        /** when true, the call came from session manager
384
          *   the method is Desktop::terminateQuickstarterToo()
385
          *   this the only one place where set this to true
386
          *   In this case,  when one frame break, not make
387
          *   question for other, the break of shutdown or logout
388
          *   can be only once.
389
          *   In Desktop::impl_closeFrames would be test and break
390
          *   the loop and reset to false
391
          */
392
        bool m_bSession;
393
394
        css::uno::Reference< css::uno::XComponentContext >              m_xContext;               /// reference to factory, which has create this instance
395
        FrameContainer                                                  m_aChildTaskContainer;    /// array of child tasks (children of desktop are tasks; and tasks are also frames - But pure frames are not accepted!)
396
        comphelper::OMultiTypeInterfaceContainerHelper2                 m_aListenerContainer;     /// container for ALL Listener
397
        rtl::Reference< OFrames >                                       m_xFramesHelper;          /// helper for XFrames, XIndexAccess, XElementAccess and implementation of a childcontainer!
398
        rtl::Reference< InterceptionHelper >                            m_xDispatchHelper;        /// helper to dispatch something for new tasks, created by "_blank"!
399
        ELoadState                                                      m_eLoadState;             /// hold information about state of asynchron loading of component for loadComponentFromURL()!
400
        bool                                                            m_bSuspendQuickstartVeto; /// don't ask quickstart for a veto
401
        std::unique_ptr<SvtCommandOptions>                              m_xCommandOptions;        /// ref counted class to support disabling commands defined by configuration file
402
        OUString                                                        m_sName;
403
        OUString                                                        m_sTitle;
404
        css::uno::Reference< css::frame::XDispatchRecorderSupplier >    m_xDispatchRecorderSupplier;
405
406
        /** special terminate listener to close pipe and block external requests
407
          * during/after termination process is/was running
408
          */
409
        css::uno::Reference< css::frame::XTerminateListener > m_xPipeTerminator;
410
411
        /** special terminate listener shown inside system tray (quick starter)
412
          * Will hinder the office on shutdown ... but wish to allow closing
413
          * of open documents. And because that's different to a normal terminate listener
414
          * it has to be handled special .-)
415
          */
416
        css::uno::Reference< css::frame::XTerminateListener > m_xQuickLauncher;
417
418
        /** special terminate listener which loads images asynchronous for current open documents.
419
          * Because internally it uses blocking system APIs... it can't be guaranteed that
420
          * running jobs can be cancelled successfully if the corresponding document will be closed...
421
          * it will not hinder those documents on closing. Instead it let all jobs running...
422
          * but at least on terminate we have to wait for all those blocked requests.
423
          * So these implementation must be a special terminate listener too .-(
424
          */
425
        css::uno::Reference< css::frame::XTerminateListener > m_xSWThreadManager;
426
427
        /** special terminate listener shutting down the SfxApplication.
428
          * Because these desktop instance closes documents and informs listener
429
          * only... it does not really shutdown the whole application.
430
          *
431
          * Btw: that wouldn't be possible by design... because Desktop.terminate()
432
          * has to return a boolean value about success... it can't really shutdown the
433
          * process .-)
434
          *
435
          * So we uses a trick: a special listener (exactly these one here) listen for notifyTermination()
436
          * and shutdown the process asynchronous. But desktop has to make this special
437
          * notification as really last one ... Otherwise it can happen that asynchronous
438
          * shutdown will be faster then all other code around Desktop.terminate() .-))
439
          */
440
        css::uno::Reference< css::frame::XTerminateListener > m_xSfxTerminator;
441
442
        rtl::Reference< ::comphelper::NumberedCollection > m_xTitleNumberGenerator;
443
444
        std::vector<css::uno::Reference<css::frame::XTerminateListener>> m_xComponentDllListeners;
445
446
};      //  class Desktop
447
448
FWK_DLLPUBLIC const rtl::Reference<Desktop> & getDesktop(
449
    css::uno::Reference<css::uno::XComponentContext> const & context);
450
451
}       //  namespace framework
452
453
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */