Coverage Report

Created: 2026-05-16 09:25

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libreoffice/sfx2/source/control/ctrlitem.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/log.hxx>
21
#include <svl/itempool.hxx>
22
#include <tools/mapunit.hxx>
23
24
#include <sfx2/ctrlitem.hxx>
25
#include <sfx2/bindings.hxx>
26
#include <sfx2/dispatch.hxx>
27
#include <statcach.hxx>
28
#include <sfx2/viewfrm.hxx>
29
30
// returns the next registered SfxControllerItem with the same id
31
32
SfxControllerItem* SfxControllerItem::GetItemLink()
33
100k
{
34
100k
    return pNext == this ? nullptr : pNext;
35
100k
}
36
37
38
// returns sal_True if this binding is really bound to a function
39
40
bool SfxControllerItem::IsBound() const
41
160k
{
42
160k
    return pNext != this;
43
160k
}
44
45
46
// registers with the id at the bindings
47
48
void SfxControllerItem::Bind( sal_uInt16 nNewId, SfxBindings *pBindinx )
49
80.4k
{
50
80.4k
    DBG_ASSERT(pBindings || pBindinx, "No Bindings");
51
52
80.4k
    if ( IsBound() ) {
53
0
        DBG_ASSERT(pBindings, "No Bindings");
54
0
        pBindings->Release(*this);
55
0
    }
56
57
80.4k
    nId = nNewId;
58
80.4k
    pNext = nullptr;
59
60
80.4k
    if (pBindinx)
61
80.4k
        pBindings = pBindinx;
62
80.4k
    pBindings->Register(*this);
63
80.4k
}
64
65
void SfxControllerItem::BindInternal_Impl( sal_uInt16 nNewId, SfxBindings *pBindinx )
66
0
{
67
0
    DBG_ASSERT(pBindings || pBindinx, "No Bindings");
68
69
0
    if ( IsBound() ) {
70
0
        DBG_ASSERT(pBindings, "No Bindings");
71
0
        pBindings->Release(*this);
72
0
    }
73
74
0
    nId = nNewId;
75
0
    pNext = nullptr;
76
77
0
    if (pBindinx)
78
0
        pBindings = pBindinx;
79
0
    pBindings->RegisterInternal_Impl(*this);
80
0
}
81
82
83
void SfxControllerItem::UnBind()
84
85
/*  [Description]
86
87
    Unbinds the connection of this SfxControllerItems with the SfxBindings
88
    instance with which it to time is bound. From this time on it does not
89
    receive any status notifications (<SfxControllerItem::StateChented()>)
90
    anymore.
91
92
    [Cross-reference]
93
94
    <SfxControllerItem::ReBind()>
95
    <SfxControllerItem::ClearCache()>
96
*/
97
80.4k
{
98
80.4k
    DBG_ASSERT(pBindings, "No Bindings");
99
80.4k
    DBG_ASSERT( IsBound(), "unbindings unbound SfxControllerItem" );
100
101
80.4k
    pBindings->Release(*this);
102
80.4k
    pNext = this;
103
80.4k
}
104
105
106
void SfxControllerItem::ReBind()
107
108
/*  [Description]
109
110
    Binds this SfxControllerItem with the SfxBindings instance again,
111
    with which it was last bound. From this time on it does receive status
112
    notifications (<SfxControllerItem::StateChented()>) again.
113
114
    [Cross-reference]
115
116
    <SfxControllerItem::UnBind()>
117
    <SfxControllerItem::ClearCache()>
118
*/
119
120
0
{
121
0
    DBG_ASSERT(pBindings, "No Bindings");
122
0
    DBG_ASSERT( !IsBound(), "bindings rebound SfxControllerItem" );
123
124
0
    pBindings->Register(*this);
125
0
}
126
127
128
void SfxControllerItem::ClearCache()
129
130
/*  [Description]
131
132
    Clears the cache status for this SfxControllerItem. That is by the next
133
    status update is the <SfxPoolItem> sent in any case, even if the same was
134
    sent before. This is needed if a controller can be switched on and note
135
    that status themselves.
136
137
    [Example]
138
139
    The combined controller for adjusting the surface type and the concrete
140
    expression (blue color, or hatching X) can be changed in type, but is then
141
    notified of the next selection again, even if it the same data.
142
143
    [Cross-reference]
144
145
    <SfxControllerItem::UnBind()>
146
    <SfxControllerItem::ReBind()>
147
*/
148
149
150
0
{
151
0
    DBG_ASSERT(pBindings, "No Bindings");
152
153
0
    pBindings->ClearCache_Impl( GetId() );
154
0
}
155
156
// replaces the successor in the list of bindings of the same id
157
SfxControllerItem* SfxControllerItem::ChangeItemLink( SfxControllerItem* pNewLink )
158
100k
{
159
100k
    SfxControllerItem* pOldLink = pNext;
160
100k
    pNext = pNewLink;
161
100k
    return pOldLink == this ? nullptr : pOldLink;
162
100k
}
163
164
165
// changes the id of unbound functions (e.g. for sub-menu-ids)
166
void SfxControllerItem::SetId( sal_uInt16 nItemId )
167
0
{
168
0
    DBG_ASSERT( !IsBound(), "changing id of bound binding" );
169
0
    nId = nItemId;
170
0
}
171
172
// creates an atomic item for a controller without registration.
173
SfxControllerItem::SfxControllerItem()
174
0
    : pNext(this)
175
0
    , pBindings(nullptr)
176
0
    , eFallbackCoreMetric(MapUnit::Map100thMM)
177
0
    , nId(0)
178
0
{
179
0
}
180
181
// creates a representation of the function nId and registers it
182
SfxControllerItem::SfxControllerItem(sal_uInt16 nID, SfxBindings &rBindings)
183
80.4k
    : pNext(this)
184
80.4k
    , pBindings(&rBindings)
185
80.4k
    , eFallbackCoreMetric(MapUnit::Map100thMM)
186
80.4k
    , nId(nID)
187
80.4k
{
188
80.4k
    Bind(nId, &rBindings);
189
80.4k
}
190
191
// unregisters the item in the bindings
192
SfxControllerItem::~SfxControllerItem()
193
80.4k
{
194
80.4k
    dispose();
195
80.4k
}
196
197
void SfxControllerItem::dispose()
198
80.4k
{
199
80.4k
    if ( IsBound() )
200
0
        UnBind();
201
80.4k
}
202
203
void SfxControllerItem::StateChangedAtToolBoxControl
204
(
205
    sal_uInt16,          // <SID> of the triggering slot
206
    SfxItemState,       // <SfxItemState> of 'pState'
207
    const SfxPoolItem*  // Slot-Status, NULL or IsInvalidItem()
208
)
209
210
/*  [Description]
211
212
    This virtual method is called by the SFx to inform the <SfxControllerItem>s
213
    is about that state of the slots 'NSID' has changed. The new value and the
214
    value determined by this status is given as 'pState' or 'eState'.
215
216
    The status of a slot may change, for example when the MDI window is
217
    switched or when the slot was invalidated explicitly with
218
    <SfxBindings::Invalidate()>.
219
220
    Beware! The method is not called when the slot is invalid, however
221
    has again assumed the same value.
222
223
    This base class need not be called, further interim steps however
224
    (eg <SfxToolboxControl> ) should be called.
225
*/
226
227
0
{
228
0
}
229
230
void SfxControllerItem::GetControlState
231
(
232
    sal_uInt16,
233
    boost::property_tree::ptree&
234
)
235
0
{
236
0
}
237
238
SfxItemState SfxControllerItem::GetItemState
239
(
240
    const SfxPoolItem* pState   /*  Pointer to  <SfxPoolItem>, which
241
                                    Status should be queried. */
242
)
243
244
/*  [Description]
245
246
    Static method to determine the status of the SfxPoolItem-Pointers, to be
247
    used in the method <SfxControllerItem::StateChanged(const SfxPoolItem*)>
248
249
    [Return value]
250
251
    SfxItemState        SfxItemState::UNKNOWN
252
                        Enabled, but no further status information available.
253
                        Typical for <Slot>s, which anyway are sometimes
254
                        disabled, but otherwise do not change their appearance.
255
256
                        SfxItemState::DISABLED
257
                        Disabled and no further status information available.
258
                        All other values that may appear should be reset to
259
                        default.
260
261
                        SfxItemState::INVALID
262
                        Enabled but there were only ambiguous values available
263
                        (i.e. non that can be queried).
264
265
                        SfxItemState::DEFAULT
266
                        Enabled and with available values, which are queried
267
                        by 'pState'. The Type is thus clearly defined in the
268
                        entire Program and specified through the Slot.
269
*/
270
271
0
{
272
0
    return !pState
273
0
                ? SfxItemState::DISABLED
274
0
                : IsInvalidItem(pState)
275
0
                    ? SfxItemState::INVALID
276
0
                    : IsDisabledItem(pState)
277
0
                        ? SfxItemState::UNKNOWN
278
0
                        : SfxItemState::DEFAULT;
279
0
}
280
281
282
MapUnit SfxControllerItem::GetCoreMetric() const
283
284
/*  [Description]
285
286
    Gets the measurement unit from the competent pool, in which the Status
287
    item exist.
288
*/
289
290
0
{
291
0
    SfxStateCache *pCache = pBindings->GetStateCache( nId );
292
0
    SfxDispatcher *pDispat = pBindings->GetDispatcher_Impl();
293
294
0
    if ( !pDispat )
295
0
    {
296
0
        SfxViewFrame* pViewFrame = SfxViewFrame::Current();
297
0
        if ( pViewFrame )
298
0
            pDispat = pViewFrame->GetDispatcher();
299
0
    }
300
301
0
    if ( pDispat && pCache )
302
0
    {
303
0
        const SfxSlotServer *pServer = pCache->GetSlotServer( *pDispat );
304
0
        if ( pServer )
305
0
        {
306
0
            if (SfxShell *pSh = pDispat->GetShell( pServer->GetShellLevel() ))
307
0
            {
308
0
                SfxItemPool &rPool = pSh->GetPool();
309
0
                sal_uInt16 nWhich = rPool.GetWhichIDFromSlotID( nId );
310
311
                // invalidate slot and its message|slot server as 'global' information
312
                // about the validated message|slot server is not made available
313
0
                pCache->Invalidate( true );
314
315
0
                return rPool.GetMetric( nWhich );
316
0
            }
317
0
        }
318
0
    }
319
320
0
    SAL_INFO( "sfx.control", "W1: Can not find ItemPool!" );
321
0
    return eFallbackCoreMetric;
322
0
}
323
324
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */