Coverage Report

Created: 2026-03-31 11:00

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libreoffice/sfx2/source/appl/appdispatchprovider.cxx
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
#include <sal/config.h>
21
22
#include <com/sun/star/frame/XAppDispatchProvider.hpp>
23
#include <com/sun/star/frame/XDispatch.hpp>
24
#include <com/sun/star/frame/XFrame.hpp>
25
#include <com/sun/star/frame/DispatchDescriptor.hpp>
26
#include <com/sun/star/lang/IllegalArgumentException.hpp>
27
#include <com/sun/star/lang/XInitialization.hpp>
28
#include <com/sun/star/lang/XServiceInfo.hpp>
29
#include <com/sun/star/util/URL.hpp>
30
31
#include <comphelper/sequence.hxx>
32
#include <cppuhelper/implbase.hxx>
33
#include <cppuhelper/supportsservice.hxx>
34
#include <rtl/ref.hxx>
35
#include <sfx2/app.hxx>
36
#include <sfx2/dispatch.hxx>
37
#include <sfx2/msg.hxx>
38
#include <sfx2/msgpool.hxx>
39
#include <sfx2/sfxbasecontroller.hxx>
40
#include <unoctitm.hxx>
41
#include <vcl/svapp.hxx>
42
43
using namespace ::com::sun::star;
44
using namespace ::com::sun::star::frame;
45
using namespace ::com::sun::star::uno;
46
47
namespace {
48
49
class SfxAppDispatchProvider : public ::cppu::WeakImplHelper< css::frame::XAppDispatchProvider,
50
                                                               css::lang::XServiceInfo,
51
                                                               css::lang::XInitialization >
52
{
53
    css::uno::WeakReference < css::frame::XFrame > m_xFrame;
54
public:
55
0
    SfxAppDispatchProvider() {}
56
57
    virtual void SAL_CALL initialize(
58
        css::uno::Sequence<css::uno::Any> const & aArguments) override;
59
60
    virtual OUString SAL_CALL getImplementationName() override;
61
62
    virtual sal_Bool SAL_CALL supportsService(OUString const & ServiceName) override;
63
64
    virtual css::uno::Sequence<OUString> SAL_CALL getSupportedServiceNames() override;
65
66
    virtual css::uno::Reference < css::frame::XDispatch > SAL_CALL queryDispatch(
67
            const css::util::URL& aURL, const OUString& sTargetFrameName,
68
            sal_Int32 eSearchFlags ) override;
69
70
    virtual css::uno::Sequence< css::uno::Reference < css::frame::XDispatch > > SAL_CALL queryDispatches(
71
            const css::uno::Sequence < css::frame::DispatchDescriptor >& seqDescriptor ) override;
72
73
    virtual css::uno::Sequence< sal_Int16 > SAL_CALL getSupportedCommandGroups() override;
74
75
    virtual css::uno::Sequence< css::frame::DispatchInformation > SAL_CALL getConfigurableDispatchInformation( sal_Int16 ) override;
76
};
77
78
void SfxAppDispatchProvider::initialize(
79
    css::uno::Sequence<css::uno::Any> const & aArguments)
80
0
{
81
0
    css::uno::Reference<css::frame::XFrame> f;
82
0
    if (aArguments.getLength() != 1 || !(aArguments[0] >>= f)) {
83
0
        throw css::lang::IllegalArgumentException(
84
0
            u"SfxAppDispatchProvider::initialize expects one XFrame argument"_ustr,
85
0
            getXWeak(), 0);
86
0
    }
87
0
    m_xFrame = f;
88
0
}
89
90
OUString SAL_CALL SfxAppDispatchProvider::getImplementationName()
91
0
{
92
0
    return u"com.sun.star.comp.sfx2.AppDispatchProvider"_ustr;
93
0
}
94
95
sal_Bool SAL_CALL SfxAppDispatchProvider::supportsService( const OUString& sServiceName )
96
0
{
97
0
    return cppu::supportsService(this, sServiceName);
98
0
}
99
100
css::uno::Sequence< OUString > SAL_CALL SfxAppDispatchProvider::getSupportedServiceNames()
101
0
{
102
0
    return { u"com.sun.star.frame.ProtocolHandler"_ustr, u"com.sun.star.frame.AppDispatchProvider"_ustr };
103
0
}
104
105
Reference < XDispatch > SAL_CALL SfxAppDispatchProvider::queryDispatch(
106
    const util::URL& aURL,
107
    const OUString& /*sTargetFrameName*/,
108
    sal_Int32 /*eSearchFlags*/ )
109
0
{
110
0
    SolarMutexGuard guard;
111
112
0
    bool                bMasterCommand( false );
113
0
    const SfxSlot* pSlot = nullptr;
114
0
    SfxApplication* pApp = SfxGetpApp();
115
0
    if ( !pApp )
116
0
        return nullptr;
117
0
    SfxDispatcher* pAppDisp = pApp->GetAppDispatcher_Impl();
118
0
    if ( aURL.Protocol == "slot:" || aURL.Protocol == "commandId:" )
119
0
    {
120
0
        sal_uInt16 nId = static_cast<sal_uInt16>(aURL.Path.toInt32());
121
0
        SfxShell* pShell;
122
0
        pAppDisp->GetShellAndSlot_Impl( nId, &pShell, &pSlot, true, true );
123
0
    }
124
0
    else if ( aURL.Protocol == ".uno:" )
125
0
    {
126
        // Support ".uno" commands. Map commands to slotid
127
0
        bMasterCommand = SfxOfficeDispatch::IsMasterUnoCommand( aURL );
128
0
        if ( bMasterCommand )
129
0
            pSlot = pAppDisp->GetSlot( SfxOfficeDispatch::GetMasterUnoCommand( aURL ) );
130
0
        else
131
0
            pSlot = pAppDisp->GetSlot( aURL.Main );
132
0
    }
133
134
0
    if ( !pSlot )
135
0
        return nullptr;
136
137
0
    rtl::Reference<SfxOfficeDispatch> pDispatch = new SfxOfficeDispatch( pAppDisp, pSlot, aURL ) ;
138
0
    pDispatch->SetFrame(m_xFrame);
139
0
    pDispatch->SetMasterUnoCommand( bMasterCommand );
140
141
0
    return pDispatch;
142
0
}
143
144
Sequence< Reference < XDispatch > > SAL_CALL SfxAppDispatchProvider::queryDispatches( const Sequence < DispatchDescriptor >& seqDescriptor )
145
0
{
146
0
    sal_Int32 nCount = seqDescriptor.getLength();
147
0
    uno::Sequence< uno::Reference < frame::XDispatch > > lDispatcher(nCount);
148
0
    std::transform(seqDescriptor.begin(), seqDescriptor.end(), lDispatcher.getArray(),
149
0
        [this](const DispatchDescriptor& rDescr) -> uno::Reference<frame::XDispatch> {
150
0
            return queryDispatch(rDescr.FeatureURL, rDescr.FrameName, rDescr.SearchFlags); });
151
0
    return lDispatcher;
152
0
}
153
154
Sequence< sal_Int16 > SAL_CALL SfxAppDispatchProvider::getSupportedCommandGroups()
155
0
{
156
0
    SolarMutexGuard aGuard;
157
158
0
    std::vector< sal_Int16 > aGroupList;
159
0
    SfxSlotPool& rAppSlotPool = SfxGetpApp()->GetAppSlotPool_Impl();
160
161
0
    const SfxSlotMode nMode( SfxSlotMode::TOOLBOXCONFIG|SfxSlotMode::ACCELCONFIG|SfxSlotMode::MENUCONFIG );
162
163
    // Select group ( group 0 is internal )
164
0
    for (sal_uInt16 i=0; i< rAppSlotPool.GetGroupCount(); ++i)
165
0
    {
166
0
        rAppSlotPool.SeekGroup(i);
167
0
        const SfxSlot* pSfxSlot = rAppSlotPool.FirstSlot();
168
0
        while ( pSfxSlot )
169
0
        {
170
0
            if ( pSfxSlot->GetMode() & nMode )
171
0
            {
172
0
                sal_Int16 nCommandGroup = MapGroupIDToCommandGroup( pSfxSlot->GetGroupId() );
173
0
                aGroupList.push_back( nCommandGroup );
174
0
                break;
175
0
            }
176
0
            pSfxSlot = rAppSlotPool.NextSlot();
177
0
        }
178
0
    }
179
180
0
    return comphelper::containerToSequence( aGroupList );
181
0
}
182
183
Sequence< frame::DispatchInformation > SAL_CALL SfxAppDispatchProvider::getConfigurableDispatchInformation( sal_Int16 nCmdGroup )
184
0
{
185
0
    std::vector< frame::DispatchInformation > aCmdVector;
186
187
0
    SolarMutexGuard aGuard;
188
0
    SfxSlotPool& rAppSlotPool = SfxGetpApp()->GetAppSlotPool_Impl();
189
190
0
    const SfxSlotMode nMode( SfxSlotMode::TOOLBOXCONFIG|SfxSlotMode::ACCELCONFIG|SfxSlotMode::MENUCONFIG );
191
192
    // Select group ( group 0 is internal )
193
0
    for (sal_uInt16 i=0; i< rAppSlotPool.GetGroupCount(); ++i)
194
0
    {
195
0
        rAppSlotPool.SeekGroup(i);
196
0
        const SfxSlot* pSfxSlot = rAppSlotPool.FirstSlot();
197
0
        if ( pSfxSlot )
198
0
        {
199
0
            sal_Int16 nCommandGroup = MapGroupIDToCommandGroup( pSfxSlot->GetGroupId() );
200
0
            if ( nCommandGroup == nCmdGroup )
201
0
            {
202
0
                while ( pSfxSlot )
203
0
                {
204
0
                    if ( pSfxSlot->GetMode() & nMode )
205
0
                    {
206
0
                        frame::DispatchInformation aCmdInfo;
207
0
                        aCmdInfo.Command = pSfxSlot->GetCommand();
208
0
                        aCmdInfo.GroupId = nCommandGroup;
209
0
                        aCmdVector.push_back( aCmdInfo );
210
0
                    }
211
0
                    pSfxSlot = rAppSlotPool.NextSlot();
212
0
                }
213
0
            }
214
0
        }
215
0
    }
216
217
0
    return comphelper::containerToSequence( aCmdVector );
218
0
}
219
220
}
221
222
extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface *
223
com_sun_star_comp_sfx2_AppDispatchProvider_get_implementation(
224
    css::uno::XComponentContext *,
225
    css::uno::Sequence<css::uno::Any> const &)
226
0
{
227
0
    return cppu::acquire(new SfxAppDispatchProvider);
228
0
}
229
230
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */