Coverage Report

Created: 2025-12-08 09:28

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
76.2M
{
37
76.2M
    return static_cast<int>(*static_cast<sal_uInt16 const *>(pSmaller)) -
38
76.2M
           static_cast<int>(static_cast<SfxSlot const *>(pBigger)->GetSlotId());
39
76.2M
}
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.99k
        nPos(n),
55
1.99k
        nFlags(f),
56
1.99k
        nObjId(nId),
57
1.99k
        bContext(false),
58
1.99k
        nFeature(nFeat)
59
1.99k
    {
60
1.99k
    }
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
725
        : eStatBarResId(StatusBarId::None)
76
725
    {
77
725
    }
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
725
    pName(pClassName),
89
725
    pGenoType(pParent),
90
725
    nClassId(nId),
91
725
    bSuperClass(bUsableSuperClass),
92
725
    pImplData(new SfxInterface_Impl)
93
725
{
94
725
    SetSlotMap( rSlotMap, nSlotCount );
95
725
}
96
97
void SfxInterface::Register( const SfxModule* pMod )
98
725
{
99
725
    if ( pMod )
100
564
        pMod->GetSlotPool()->RegisterInterface(*this);
101
161
    else
102
161
        SfxGetpApp()->GetAppSlotPool_Impl().RegisterInterface(*this);
103
725
}
104
105
void SfxInterface::SetSlotMap( const SfxSlot& rSlotMap, sal_uInt16 nSlotCount )
106
725
{
107
725
    pSlots = &rSlotMap;
108
725
    nCount = nSlotCount;
109
725
    const SfxSlot* pIter = pSlots;
110
111
725
    if ( !pIter->pNextSlot )
112
89
    {
113
89
        assert(std::is_sorted(pSlots, pSlots + nCount,
114
89
            [](const SfxSlot& rLHS, const SfxSlot& rRHS)
115
89
            {
116
89
                return rLHS.GetSlotId() < rRHS.GetSlotId();
117
89
            }));
118
89
    }
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
725
}
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
15.5M
{
158
159
15.5M
    assert( pSlots );
160
15.5M
    assert( nCount );
161
162
    // find the id using binary search
163
15.5M
    void* p = bsearch( &nFuncId, pSlots, nCount, sizeof(SfxSlot),
164
15.5M
                       SfxCompareSlots_bsearch );
165
15.5M
    if ( !p && pGenoType )
166
8.18M
        return pGenoType->GetSlot( nFuncId );
167
168
7.34M
    return static_cast<const SfxSlot*>(p);
169
15.5M
}
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
344
{
209
344
    pImplData->aPopupName = rResourceName;
210
344
}
211
212
void SfxInterface::RegisterObjectBar(sal_uInt16 nPos, SfxVisibilityFlags nFlags, ToolbarId eId)
213
385
{
214
385
    RegisterObjectBar(nPos, nFlags, eId, SfxShellFeature::NONE);
215
385
}
216
217
void SfxInterface::RegisterObjectBar(sal_uInt16 nPos, SfxVisibilityFlags nFlags, ToolbarId eId, SfxShellFeature nFeature)
218
515
{
219
515
    pImplData->aObjectBars.emplace_back( CreateObjectBarUI_Impl(nPos, nFlags, eId, nFeature) );
220
515
}
221
222
SfxObjectUI_Impl CreateObjectBarUI_Impl(sal_uInt16 nPos, SfxVisibilityFlags nFlags, ToolbarId eId, SfxShellFeature nFeature)
223
515
{
224
515
    if (nFlags == SfxVisibilityFlags::Invisible)
225
182
        nFlags |= SfxVisibilityFlags::Standard;
226
227
515
    return SfxObjectUI_Impl(nPos, nFlags, static_cast<sal_uInt32>(eId), nFeature);
228
515
}
229
230
ToolbarId SfxInterface::GetObjectBarId(sal_uInt16 nNo) const
231
21.3k
{
232
21.3k
    bool bGenoType = (pGenoType != nullptr && pGenoType->UseAsSuperClass());
233
21.3k
    if ( bGenoType )
234
12.8k
    {
235
        // Are there toolbars in the super class?
236
12.8k
        sal_uInt16 nBaseCount = pGenoType->GetObjectBarCount();
237
12.8k
        if ( nNo < nBaseCount )
238
            // The Super class comes first
239
0
            return pGenoType->GetObjectBarId(nNo);
240
12.8k
        else
241
12.8k
            nNo = nNo - nBaseCount;
242
12.8k
    }
243
244
21.3k
    assert( nNo<pImplData->aObjectBars.size() );
245
246
21.3k
    return static_cast<ToolbarId>(pImplData->aObjectBars[nNo].nObjId);
247
21.3k
}
248
249
sal_uInt16 SfxInterface::GetObjectBarPos( sal_uInt16 nNo ) const
250
42.6k
{
251
42.6k
    bool bGenoType = (pGenoType != nullptr && pGenoType->UseAsSuperClass());
252
42.6k
    if ( bGenoType )
253
21.3k
    {
254
        // Are there toolbars in the super class?
255
21.3k
        sal_uInt16 nBaseCount = pGenoType->GetObjectBarCount();
256
21.3k
        if ( nNo < nBaseCount )
257
            // The Super class comes first
258
0
            return pGenoType->GetObjectBarPos( nNo );
259
21.3k
        else
260
21.3k
            nNo = nNo - nBaseCount;
261
21.3k
    }
262
263
42.6k
    assert( nNo<pImplData->aObjectBars.size() );
264
265
42.6k
    return pImplData->aObjectBars[nNo].nPos;
266
42.6k
}
267
268
SfxVisibilityFlags SfxInterface::GetObjectBarFlags( sal_uInt16 nNo ) const
269
42.6k
{
270
42.6k
    bool bGenoType = (pGenoType != nullptr && pGenoType->UseAsSuperClass());
271
42.6k
    if ( bGenoType )
272
21.3k
    {
273
        // Are there toolbars in the super class?
274
21.3k
        sal_uInt16 nBaseCount = pGenoType->GetObjectBarCount();
275
21.3k
        if ( nNo < nBaseCount )
276
            // The Super class comes first
277
0
            return pGenoType->GetObjectBarFlags( nNo );
278
21.3k
        else
279
21.3k
            nNo = nNo - nBaseCount;
280
21.3k
    }
281
282
42.6k
    assert( nNo<pImplData->aObjectBars.size() );
283
284
42.6k
    return pImplData->aObjectBars[nNo].nFlags;
285
42.6k
}
286
287
sal_uInt16 SfxInterface::GetObjectBarCount() const
288
243k
{
289
243k
    if (pGenoType && pGenoType->UseAsSuperClass())
290
55.4k
        return pImplData->aObjectBars.size() + pGenoType->GetObjectBarCount();
291
187k
    else
292
187k
        return pImplData->aObjectBars.size();
293
243k
}
294
295
void SfxInterface::RegisterChildWindow(sal_uInt16 nId, bool bContext)
296
1.33k
{
297
1.33k
    RegisterChildWindow(nId, bContext, SfxShellFeature::NONE);
298
1.33k
}
299
300
void SfxInterface::RegisterChildWindow(sal_uInt16 nId, bool bContext, SfxShellFeature nFeature)
301
1.47k
{
302
1.47k
    SfxObjectUI_Impl aUI(0, SfxVisibilityFlags::Invisible, nId, nFeature);
303
1.47k
    aUI.bContext = bContext;
304
1.47k
    pImplData->aChildWindows.emplace_back(aUI);
305
1.47k
}
306
307
void SfxInterface::RegisterStatusBar(StatusBarId eId)
308
54
{
309
54
    pImplData->eStatBarResId = eId;
310
54
}
311
312
sal_uInt32 SfxInterface::GetChildWindowId (sal_uInt16 nNo) const
313
302k
{
314
302k
    if ( pGenoType )
315
153k
    {
316
        // Are there ChildWindows in the superclass?
317
153k
        sal_uInt16 nBaseCount = pGenoType->GetChildWindowCount();
318
153k
        if ( nNo < nBaseCount )
319
            // The Super class comes first
320
25.6k
            return pGenoType->GetChildWindowId( nNo );
321
127k
        else
322
127k
            nNo = nNo - nBaseCount;
323
153k
    }
324
325
302k
    assert( nNo<pImplData->aChildWindows.size() );
326
327
277k
    sal_uInt32 nRet = pImplData->aChildWindows[nNo].nObjId;
328
277k
    if ( pImplData->aChildWindows[nNo].bContext )
329
8.52k
        nRet += sal_uInt16( nClassId ) << 16;
330
277k
    return nRet;
331
302k
}
332
333
SfxShellFeature SfxInterface::GetChildWindowFeature (sal_uInt16 nNo) const
334
302k
{
335
302k
    if ( pGenoType )
336
153k
    {
337
        // Are there ChildWindows in the superclass?
338
153k
        sal_uInt16 nBaseCount = pGenoType->GetChildWindowCount();
339
153k
        if ( nNo < nBaseCount )
340
            // The Super class comes first
341
25.6k
            return pGenoType->GetChildWindowFeature( nNo );
342
127k
        else
343
127k
            nNo = nNo - nBaseCount;
344
153k
    }
345
346
302k
    assert( nNo<pImplData->aChildWindows.size() );
347
348
277k
    return pImplData->aChildWindows[nNo].nFeature;
349
302k
}
350
351
352
sal_uInt16 SfxInterface::GetChildWindowCount() const
353
827k
{
354
827k
    if (pGenoType)
355
187k
        return pImplData->aChildWindows.size() + pGenoType->GetChildWindowCount();
356
639k
    else
357
639k
        return pImplData->aChildWindows.size();
358
827k
}
359
360
const OUString& SfxInterface::GetPopupMenuName() const
361
0
{
362
0
    return pImplData->aPopupName;
363
0
}
364
365
StatusBarId SfxInterface::GetStatusBarId() const
366
81.0k
{
367
81.0k
    if (pImplData->eStatBarResId == StatusBarId::None && pGenoType)
368
25.5k
        return pGenoType->GetStatusBarId();
369
55.4k
    else
370
55.4k
        return pImplData->eStatBarResId;
371
81.0k
}
372
373
SfxShellFeature SfxInterface::GetObjectBarFeature ( sal_uInt16 nNo ) const
374
42.6k
{
375
42.6k
    bool bGenoType = (pGenoType != nullptr && pGenoType->UseAsSuperClass());
376
42.6k
    if ( bGenoType )
377
21.3k
    {
378
        // Are there toolbars in the super class?
379
21.3k
        sal_uInt16 nBaseCount = pGenoType->GetObjectBarCount();
380
21.3k
        if ( nNo < nBaseCount )
381
            // The Super class comes first
382
0
            return pGenoType->GetObjectBarFeature( nNo );
383
21.3k
        else
384
21.3k
            nNo = nNo - nBaseCount;
385
21.3k
    }
386
387
42.6k
    assert( nNo<pImplData->aObjectBars.size() );
388
389
42.6k
    return pImplData->aObjectBars[nNo].nFeature;
390
42.6k
}
391
392
bool SfxInterface::IsObjectBarVisible(sal_uInt16 nNo) const
393
21.3k
{
394
21.3k
    bool bGenoType = (pGenoType != nullptr && pGenoType->UseAsSuperClass());
395
21.3k
    if ( bGenoType )
396
12.8k
    {
397
        // Are there toolbars in the super class?
398
12.8k
        sal_uInt16 nBaseCount = pGenoType->GetObjectBarCount();
399
12.8k
        if ( nNo < nBaseCount )
400
            // The Super class comes first
401
0
            return pGenoType->IsObjectBarVisible( nNo );
402
12.8k
        else
403
12.8k
            nNo = nNo - nBaseCount;
404
12.8k
    }
405
406
21.3k
    assert( nNo<pImplData->aObjectBars.size() );
407
408
21.3k
    return true;
409
21.3k
}
410
411
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */