Coverage Report

Created: 2026-08-14 10:22

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libreoffice/sfx2/source/control/objface.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 <assert.h>
21
#include <stdlib.h>
22
23
#include <sal/log.hxx>
24
25
#include <sfx2/module.hxx>
26
#include <sfx2/objface.hxx>
27
#include <sfx2/msg.hxx>
28
#include <sfx2/app.hxx>
29
#include <sfx2/msgpool.hxx>
30
31
extern "C" {
32
33
34
static int
35
SfxCompareSlots_bsearch( const void* pSmaller, const void* pBigger )
36
75.6M
{
37
75.6M
    return static_cast<int>(*static_cast<sal_uInt16 const *>(pSmaller)) -
38
75.6M
           static_cast<int>(static_cast<SfxSlot const *>(pBigger)->GetSlotId());
39
75.6M
}
40
41
}
42
43
namespace {
44
45
struct SfxObjectUI_Impl
46
{
47
    sal_uInt16         nPos;
48
    SfxVisibilityFlags nFlags;
49
    sal_uInt32         nObjId;
50
    bool               bContext;
51
    SfxShellFeature    nFeature;
52
53
    SfxObjectUI_Impl(sal_uInt16 n, SfxVisibilityFlags f, sal_uInt32 nId, SfxShellFeature nFeat) :
54
1.85k
        nPos(n),
55
1.85k
        nFlags(f),
56
1.85k
        nObjId(nId),
57
1.85k
        bContext(false),
58
1.85k
        nFeature(nFeat)
59
1.85k
    {
60
1.85k
    }
61
};
62
63
}
64
65
struct SfxInterface_Impl
66
{
67
    std::vector<SfxObjectUI_Impl>
68
                            aObjectBars;    // registered ObjectBars
69
    std::vector<SfxObjectUI_Impl>
70
                            aChildWindows;  // registered ChildWindows
71
    OUString                aPopupName;     // registered PopupMenu
72
    StatusBarId             eStatBarResId;  // registered StatusBar
73
74
    SfxInterface_Impl()
75
691
        : eStatBarResId(StatusBarId::None)
76
691
    {
77
691
    }
78
};
79
80
static SfxObjectUI_Impl CreateObjectBarUI_Impl(sal_uInt16 nPos, SfxVisibilityFlags nFlags, ToolbarId eId, SfxShellFeature nFeature);
81
82
// constructor, registers a new unit
83
SfxInterface::SfxInterface( const char *pClassName,
84
                            bool bUsableSuperClass,
85
                            SfxInterfaceId nId,
86
                            const SfxInterface* pParent,
87
                            const SfxSlot &rSlotMap, sal_uInt16 nSlotCount ):
88
691
    pName(pClassName),
89
691
    pGenoType(pParent),
90
691
    nClassId(nId),
91
691
    bSuperClass(bUsableSuperClass),
92
691
    pImplData(new SfxInterface_Impl)
93
691
{
94
691
    SetSlotMap( rSlotMap, nSlotCount );
95
691
}
96
97
void SfxInterface::Register( const SfxModule* pMod )
98
691
{
99
691
    if ( pMod )
100
542
        pMod->GetSlotPool()->RegisterInterface(*this);
101
149
    else
102
149
        SfxGetpApp()->GetAppSlotPool_Impl().RegisterInterface(*this);
103
691
}
104
105
void SfxInterface::SetSlotMap( const SfxSlot& rSlotMap, sal_uInt16 nSlotCount )
106
691
{
107
691
    pSlots = &rSlotMap;
108
691
    nCount = nSlotCount;
109
691
    const SfxSlot* pIter = pSlots;
110
111
691
    if ( !pIter->pNextSlot )
112
83
    {
113
83
        assert(std::is_sorted(pSlots, pSlots + nCount,
114
83
            [](const SfxSlot& rLHS, const SfxSlot& rRHS)
115
83
            {
116
83
                return rLHS.GetSlotId() < rRHS.GetSlotId();
117
83
            }));
118
83
    }
119
#ifdef DBG_UTIL
120
    else
121
    {
122
        sal_uInt16 nIter = 1;
123
        for (const SfxSlot *pNext = pIter+1; nIter < nCount; ++pNext, ++nIter)
124
        {
125
126
            if ( pNext->GetSlotId() <= pIter->GetSlotId() )
127
                SAL_WARN( "sfx.control", "Wrong order" );
128
129
            const SfxSlot *pCurSlot = pIter;
130
            do
131
            {
132
                pCurSlot = pCurSlot->pNextSlot;
133
                if ( pCurSlot->GetStateFnc() != pIter->GetStateFnc() )
134
                {
135
                    SAL_WARN("sfx.control", "Linked Slots with different State Methods : "
136
                                << pCurSlot->GetSlotId()
137
                                << " , " << pIter->GetSlotId() );
138
                }
139
            }
140
            while ( pCurSlot != pIter );
141
142
            pIter = pNext;
143
        }
144
    }
145
#endif
146
691
}
147
148
149
SfxInterface::~SfxInterface()
150
0
{
151
0
}
152
153
154
// searches for the specified func
155
156
const SfxSlot* SfxInterface::GetSlot( sal_uInt16 nFuncId ) const
157
14.8M
{
158
159
14.8M
    assert( pSlots );
160
14.8M
    assert( nCount );
161
162
    // find the id using binary search
163
14.8M
    void* p = bsearch( &nFuncId, pSlots, nCount, sizeof(SfxSlot),
164
14.8M
                       SfxCompareSlots_bsearch );
165
14.8M
    if ( !p && pGenoType )
166
7.95M
        return pGenoType->GetSlot( nFuncId );
167
168
6.88M
    return static_cast<const SfxSlot*>(p);
169
14.8M
}
170
171
const SfxSlot* SfxInterface::GetSlot( const OUString& rCommand ) const
172
0
{
173
0
    static const char UNO_COMMAND[] = ".uno:";
174
175
0
    OUString aCommand( rCommand );
176
0
    if ( aCommand.startsWith( UNO_COMMAND ) )
177
0
         aCommand = aCommand.copy( sizeof( UNO_COMMAND )-1 );
178
179
0
    for ( sal_uInt16 n=0; n<nCount; n++ )
180
0
    {
181
0
        if ( aCommand.equalsIgnoreAsciiCase( (pSlots+n)->GetUnoName() ) )
182
0
            return pSlots+n;
183
0
    }
184
185
0
    return pGenoType ? pGenoType->GetSlot( aCommand ) : nullptr;
186
0
}
187
188
189
const SfxSlot* SfxInterface::GetRealSlot( const SfxSlot *pSlot ) const
190
0
{
191
192
0
    assert( pSlots );
193
0
    assert( nCount );
194
195
0
    if ( !ContainsSlot_Impl(pSlot) )
196
0
    {
197
0
        if(pGenoType)
198
0
            return pGenoType->GetRealSlot(pSlot);
199
0
        SAL_WARN( "sfx.control", "unknown Slot" );
200
0
        return nullptr;
201
0
    }
202
203
0
    return nullptr;
204
0
}
205
206
207
void SfxInterface::RegisterPopupMenu( const OUString& rResourceName )
208
327
{
209
327
    pImplData->aPopupName = rResourceName;
210
327
}
211
212
void SfxInterface::RegisterObjectBar(sal_uInt16 nPos, SfxVisibilityFlags nFlags, ToolbarId eId)
213
367
{
214
367
    RegisterObjectBar(nPos, nFlags, eId, SfxShellFeature::NONE);
215
367
}
216
217
void SfxInterface::RegisterObjectBar(sal_uInt16 nPos, SfxVisibilityFlags nFlags, ToolbarId eId, SfxShellFeature nFeature)
218
487
{
219
487
    pImplData->aObjectBars.emplace_back( CreateObjectBarUI_Impl(nPos, nFlags, eId, nFeature) );
220
487
}
221
222
SfxObjectUI_Impl CreateObjectBarUI_Impl(sal_uInt16 nPos, SfxVisibilityFlags nFlags, ToolbarId eId, SfxShellFeature nFeature)
223
487
{
224
487
    if (nFlags == SfxVisibilityFlags::Invisible)
225
181
        nFlags |= SfxVisibilityFlags::Standard;
226
227
487
    return SfxObjectUI_Impl(nPos, nFlags, static_cast<sal_uInt32>(eId), nFeature);
228
487
}
229
230
ToolbarId SfxInterface::GetObjectBarId(sal_uInt16 nNo) const
231
20.7k
{
232
20.7k
    bool bGenoType = (pGenoType != nullptr && pGenoType->UseAsSuperClass());
233
20.7k
    if ( bGenoType )
234
12.4k
    {
235
        // Are there toolbars in the super class?
236
12.4k
        sal_uInt16 nBaseCount = pGenoType->GetObjectBarCount();
237
12.4k
        if ( nNo < nBaseCount )
238
            // The Super class comes first
239
0
            return pGenoType->GetObjectBarId(nNo);
240
12.4k
        else
241
12.4k
            nNo = nNo - nBaseCount;
242
12.4k
    }
243
244
20.7k
    assert( nNo<pImplData->aObjectBars.size() );
245
246
20.7k
    return static_cast<ToolbarId>(pImplData->aObjectBars[nNo].nObjId);
247
20.7k
}
248
249
sal_uInt16 SfxInterface::GetObjectBarPos( sal_uInt16 nNo ) const
250
41.4k
{
251
41.4k
    bool bGenoType = (pGenoType != nullptr && pGenoType->UseAsSuperClass());
252
41.4k
    if ( bGenoType )
253
20.7k
    {
254
        // Are there toolbars in the super class?
255
20.7k
        sal_uInt16 nBaseCount = pGenoType->GetObjectBarCount();
256
20.7k
        if ( nNo < nBaseCount )
257
            // The Super class comes first
258
0
            return pGenoType->GetObjectBarPos( nNo );
259
20.7k
        else
260
20.7k
            nNo = nNo - nBaseCount;
261
20.7k
    }
262
263
41.4k
    assert( nNo<pImplData->aObjectBars.size() );
264
265
41.4k
    return pImplData->aObjectBars[nNo].nPos;
266
41.4k
}
267
268
SfxVisibilityFlags SfxInterface::GetObjectBarFlags( sal_uInt16 nNo ) const
269
41.4k
{
270
41.4k
    bool bGenoType = (pGenoType != nullptr && pGenoType->UseAsSuperClass());
271
41.4k
    if ( bGenoType )
272
20.7k
    {
273
        // Are there toolbars in the super class?
274
20.7k
        sal_uInt16 nBaseCount = pGenoType->GetObjectBarCount();
275
20.7k
        if ( nNo < nBaseCount )
276
            // The Super class comes first
277
0
            return pGenoType->GetObjectBarFlags( nNo );
278
20.7k
        else
279
20.7k
            nNo = nNo - nBaseCount;
280
20.7k
    }
281
282
41.4k
    assert( nNo<pImplData->aObjectBars.size() );
283
284
41.4k
    return pImplData->aObjectBars[nNo].nFlags;
285
41.4k
}
286
287
sal_uInt16 SfxInterface::GetObjectBarCount() const
288
236k
{
289
236k
    if (pGenoType && pGenoType->UseAsSuperClass())
290
53.8k
        return pImplData->aObjectBars.size() + pGenoType->GetObjectBarCount();
291
182k
    else
292
182k
        return pImplData->aObjectBars.size();
293
236k
}
294
295
void SfxInterface::RegisterChildWindow(sal_uInt16 nId, bool bContext)
296
1.23k
{
297
1.23k
    RegisterChildWindow(nId, bContext, SfxShellFeature::NONE);
298
1.23k
}
299
300
void SfxInterface::RegisterChildWindow(sal_uInt16 nId, bool bContext, SfxShellFeature nFeature)
301
1.36k
{
302
1.36k
    SfxObjectUI_Impl aUI(0, SfxVisibilityFlags::Invisible, nId, nFeature);
303
1.36k
    aUI.bContext = bContext;
304
1.36k
    pImplData->aChildWindows.emplace_back(aUI);
305
1.36k
}
306
307
void SfxInterface::RegisterStatusBar(StatusBarId eId)
308
50
{
309
50
    pImplData->eStatBarResId = eId;
310
50
}
311
312
sal_uInt32 SfxInterface::GetChildWindowId (sal_uInt16 nNo) const
313
294k
{
314
294k
    if ( pGenoType )
315
149k
    {
316
        // Are there ChildWindows in the superclass?
317
149k
        sal_uInt16 nBaseCount = pGenoType->GetChildWindowCount();
318
149k
        if ( nNo < nBaseCount )
319
            // The Super class comes first
320
24.9k
            return pGenoType->GetChildWindowId( nNo );
321
124k
        else
322
124k
            nNo = nNo - nBaseCount;
323
149k
    }
324
325
294k
    assert( nNo<pImplData->aChildWindows.size() );
326
327
269k
    sal_uInt32 nRet = pImplData->aChildWindows[nNo].nObjId;
328
269k
    if ( pImplData->aChildWindows[nNo].bContext )
329
8.28k
        nRet += sal_uInt16( nClassId ) << 16;
330
269k
    return nRet;
331
294k
}
332
333
SfxShellFeature SfxInterface::GetChildWindowFeature (sal_uInt16 nNo) const
334
294k
{
335
294k
    if ( pGenoType )
336
149k
    {
337
        // Are there ChildWindows in the superclass?
338
149k
        sal_uInt16 nBaseCount = pGenoType->GetChildWindowCount();
339
149k
        if ( nNo < nBaseCount )
340
            // The Super class comes first
341
24.9k
            return pGenoType->GetChildWindowFeature( nNo );
342
124k
        else
343
124k
            nNo = nNo - nBaseCount;
344
149k
    }
345
346
294k
    assert( nNo<pImplData->aChildWindows.size() );
347
348
269k
    return pImplData->aChildWindows[nNo].nFeature;
349
294k
}
350
351
352
sal_uInt16 SfxInterface::GetChildWindowCount() const
353
803k
{
354
803k
    if (pGenoType)
355
182k
        return pImplData->aChildWindows.size() + pGenoType->GetChildWindowCount();
356
621k
    else
357
621k
        return pImplData->aChildWindows.size();
358
803k
}
359
360
const OUString& SfxInterface::GetPopupMenuName() const
361
0
{
362
0
    return pImplData->aPopupName;
363
0
}
364
365
StatusBarId SfxInterface::GetStatusBarId() const
366
78.7k
{
367
78.7k
    if (pImplData->eStatBarResId == StatusBarId::None && pGenoType)
368
24.8k
        return pGenoType->GetStatusBarId();
369
53.8k
    else
370
53.8k
        return pImplData->eStatBarResId;
371
78.7k
}
372
373
SfxShellFeature SfxInterface::GetObjectBarFeature ( sal_uInt16 nNo ) const
374
41.4k
{
375
41.4k
    bool bGenoType = (pGenoType != nullptr && pGenoType->UseAsSuperClass());
376
41.4k
    if ( bGenoType )
377
20.7k
    {
378
        // Are there toolbars in the super class?
379
20.7k
        sal_uInt16 nBaseCount = pGenoType->GetObjectBarCount();
380
20.7k
        if ( nNo < nBaseCount )
381
            // The Super class comes first
382
0
            return pGenoType->GetObjectBarFeature( nNo );
383
20.7k
        else
384
20.7k
            nNo = nNo - nBaseCount;
385
20.7k
    }
386
387
41.4k
    assert( nNo<pImplData->aObjectBars.size() );
388
389
41.4k
    return pImplData->aObjectBars[nNo].nFeature;
390
41.4k
}
391
392
bool SfxInterface::IsObjectBarVisible(sal_uInt16 nNo) const
393
20.7k
{
394
20.7k
    bool bGenoType = (pGenoType != nullptr && pGenoType->UseAsSuperClass());
395
20.7k
    if ( bGenoType )
396
12.4k
    {
397
        // Are there toolbars in the super class?
398
12.4k
        sal_uInt16 nBaseCount = pGenoType->GetObjectBarCount();
399
12.4k
        if ( nNo < nBaseCount )
400
            // The Super class comes first
401
0
            return pGenoType->IsObjectBarVisible( nNo );
402
12.4k
        else
403
12.4k
            nNo = nNo - nBaseCount;
404
12.4k
    }
405
406
20.7k
    assert( nNo<pImplData->aObjectBars.size() );
407
408
20.7k
    return true;
409
20.7k
}
410
411
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */