Coverage Report

Created: 2026-11-06 11:29

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libreoffice/svl/source/items/itemprop.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 <o3tl/any.hxx>
23
#include <svl/itemprop.hxx>
24
#include <svl/itempool.hxx>
25
#include <svl/itemset.hxx>
26
#include <com/sun/star/beans/PropertyAttribute.hpp>
27
#include <com/sun/star/beans/PropertyState.hpp>
28
#include <com/sun/star/lang/IllegalArgumentException.hpp>
29
#include <memory>
30
31
/*
32
 * UNO III Implementation
33
 */
34
using namespace com::sun::star;
35
using namespace com::sun::star::beans;
36
using namespace com::sun::star::lang;
37
using namespace com::sun::star::uno;
38
39
SfxItemPropertyMap::SfxItemPropertyMap( std::span<const SfxItemPropertyMapEntry> pEntries )
40
38.9k
{
41
38.9k
    m_aMap.reserve(pEntries.size());
42
38.9k
    for (const auto & pEntry : pEntries)
43
1.50M
    {
44
1.50M
        assert(!pEntry.aName.isEmpty() && "empty name? might be something left an empty entry at the end of this array");
45
1.50M
        m_aMap.insert( &pEntry );
46
1.50M
    }
47
38.9k
}
48
49
159
SfxItemPropertyMap::SfxItemPropertyMap( const SfxItemPropertyMap& rSource ) = default;
50
51
SfxItemPropertyMap::~SfxItemPropertyMap()
52
38.9k
{
53
38.9k
}
54
55
const SfxItemPropertyMapEntry* SfxItemPropertyMap::getByName( std::u16string_view rName ) const
56
35.2M
{
57
35.2M
    struct Compare
58
35.2M
    {
59
35.2M
        bool operator() ( const SfxItemPropertyMapEntry* lhs, std::u16string_view rhs ) const
60
250M
        {
61
250M
            return lhs->aName < rhs;
62
250M
        }
63
35.2M
        bool operator() ( std::u16string_view lhs, const SfxItemPropertyMapEntry* rhs ) const
64
35.2M
        {
65
35.1M
            return lhs < rhs->aName;
66
35.1M
        }
67
35.2M
    };
68
35.2M
    auto it = std::lower_bound(m_aMap.begin(), m_aMap.end(), rName, Compare());
69
35.2M
    if (it == m_aMap.end() || Compare()(rName, *it))
70
3.15M
        return nullptr;
71
32.1M
    return *it;
72
35.2M
}
73
74
uno::Sequence<beans::Property> const & SfxItemPropertyMap::getProperties() const
75
46.3k
{
76
46.3k
    if( !m_aPropSeq.hasElements() )
77
75
    {
78
75
        m_aPropSeq.realloc( m_aMap.size() );
79
75
        beans::Property* pPropArray = m_aPropSeq.getArray();
80
75
        sal_uInt32 n = 0;
81
75
        for( const SfxItemPropertyMapEntry* pEntry : m_aMap )
82
12.4k
        {
83
12.4k
            pPropArray[n].Name = pEntry->aName;
84
12.4k
            pPropArray[n].Handle = pEntry->nWID;
85
12.4k
            pPropArray[n].Type = pEntry->aType;
86
12.4k
            pPropArray[n].Attributes =
87
12.4k
                sal::static_int_cast< sal_Int16 >(pEntry->nFlags);
88
12.4k
            n++;
89
12.4k
        }
90
75
    }
91
92
46.3k
    return m_aPropSeq;
93
46.3k
}
94
95
beans::Property SfxItemPropertyMap::getPropertyByName( const OUString& rName ) const
96
0
{
97
0
    const SfxItemPropertyMapEntry* pEntry = getByName(rName);
98
0
    if( !pEntry )
99
0
        throw UnknownPropertyException(rName);
100
0
    beans::Property aProp;
101
0
    aProp.Name = rName;
102
0
    aProp.Handle = pEntry->nWID;
103
0
    aProp.Type = pEntry->aType;
104
0
    aProp.Attributes = sal::static_int_cast< sal_Int16 >(pEntry->nFlags);
105
0
    return aProp;
106
0
}
107
108
bool SfxItemPropertyMap::hasPropertyByName( std::u16string_view rName ) const
109
2.38M
{
110
2.38M
    return getByName(rName) != nullptr;
111
2.38M
}
112
113
SfxItemPropertySet::~SfxItemPropertySet()
114
37.9k
{
115
37.9k
}
116
117
// static
118
void SfxItemPropertySet::getPropertyValue( const SfxItemPropertyMapEntry& rEntry,
119
            const SfxItemSet& rSet, Any& rAny )
120
526k
{
121
    // get the SfxPoolItem
122
526k
    const SfxPoolItem* pItem = nullptr;
123
526k
    SfxItemState eState = rSet.GetItemState( rEntry.nWID, true, &pItem );
124
526k
    if (SfxItemState::SET != eState && SfxItemPool::IsWhich(rEntry.nWID) )
125
23.8k
        pItem = &rSet.GetPool()->GetUserOrPoolDefaultItem(rEntry.nWID);
126
    // return item values as uno::Any
127
526k
    if(eState >= SfxItemState::DEFAULT && pItem)
128
526k
    {
129
526k
        pItem->QueryValue( rAny, rEntry.nMemberId );
130
526k
    }
131
1
    else if(0 == (rEntry.nFlags & PropertyAttribute::MAYBEVOID))
132
0
    {
133
0
        throw RuntimeException(
134
0
            u"Property not found in ItemSet but not MAYBEVOID?"_ustr, nullptr);
135
0
    }
136
137
    // convert general SfxEnumItem values to specific values
138
526k
    if (rEntry.aType.getTypeClass() == TypeClass_ENUM
139
17.5k
        && rEntry.aType.getTypeClass() != rAny.getValueTypeClass())
140
120
    {
141
120
        if (sal_Int32 nTmp; rAny >>= nTmp)
142
120
            rAny.setValue(&nTmp, rEntry.aType);
143
120
    }
144
526k
}
145
146
void SfxItemPropertySet::getPropertyValue( const OUString &rName,
147
                                           const SfxItemSet& rSet, Any& rAny ) const
148
32.3k
{
149
    // detect which-id
150
32.3k
    const SfxItemPropertyMapEntry* pEntry = m_aMap.getByName( rName );
151
32.3k
    if ( !pEntry )
152
0
        throw UnknownPropertyException(rName);
153
32.3k
    getPropertyValue( *pEntry,rSet, rAny );
154
32.3k
}
155
156
Any SfxItemPropertySet::getPropertyValue( const OUString &rName,
157
                                          const SfxItemSet& rSet ) const
158
0
{
159
0
    Any aVal;
160
0
    getPropertyValue( rName,rSet, aVal );
161
0
    return aVal;
162
0
}
163
164
// static
165
void SfxItemPropertySet::setPropertyValue( const SfxItemPropertyMapEntry& rEntry,
166
                                           const Any& aVal,
167
                                           SfxItemSet& rSet, bool bIgnoreUnknownProperty )
168
3.16M
{
169
    // get the SfxPoolItem
170
3.16M
    const SfxPoolItem* pItem = nullptr;
171
3.16M
    SfxItemState eState = rSet.GetItemState( rEntry.nWID, true, &pItem );
172
3.16M
    if (SfxItemState::SET != eState && SfxItemPool::IsWhich(rEntry.nWID))
173
1.64M
        pItem = &rSet.GetPool()->GetUserOrPoolDefaultItem(rEntry.nWID);
174
3.16M
    if (!pItem)
175
53.4k
        return;
176
3.10M
    std::unique_ptr<SfxPoolItem> pNewItem(pItem->Clone());
177
3.10M
    if(!pNewItem)
178
0
        return;
179
3.10M
    if( !pNewItem->PutValue( aVal, rEntry.nMemberId ) )
180
1.94k
    {
181
1.94k
        if (bIgnoreUnknownProperty)
182
225
            return;
183
1.72k
        throw IllegalArgumentException();
184
1.94k
    }
185
    // apply new item
186
3.10M
    rSet.Put( std::move(pNewItem) );
187
3.10M
}
188
189
void SfxItemPropertySet::setPropertyValue( const OUString &rName,
190
                                           const Any& aVal,
191
                                           SfxItemSet& rSet, bool bIgnoreUnknownProperty ) const
192
605k
{
193
605k
    const SfxItemPropertyMapEntry* pEntry = m_aMap.getByName( rName );
194
605k
    if ( !pEntry )
195
0
    {
196
0
        if (bIgnoreUnknownProperty)
197
0
            return;
198
0
        throw UnknownPropertyException(rName);
199
0
    }
200
605k
    setPropertyValue(*pEntry, aVal, rSet, bIgnoreUnknownProperty);
201
605k
}
202
203
// static
204
PropertyState SfxItemPropertySet::getPropertyState(const SfxItemPropertyMapEntry& rEntry, const SfxItemSet& rSet)
205
    noexcept
206
2.68M
{
207
2.68M
    PropertyState eRet = PropertyState_DIRECT_VALUE;
208
2.68M
    sal_uInt16 nWhich = rEntry.nWID;
209
210
    // Get item state
211
2.68M
    SfxItemState eState = rSet.GetItemState( nWhich, false );
212
    // Return item value as UnoAny
213
2.68M
    if(eState == SfxItemState::DEFAULT)
214
2.40M
        eRet = PropertyState_DEFAULT_VALUE;
215
278k
    else if(eState < SfxItemState::DEFAULT)
216
75.3k
        eRet = PropertyState_AMBIGUOUS_VALUE;
217
2.68M
    return eRet;
218
2.68M
}
219
220
PropertyState   SfxItemPropertySet::getPropertyState(const OUString& rName, const SfxItemSet& rSet) const
221
0
{
222
0
    PropertyState eRet = PropertyState_DIRECT_VALUE;
223
224
    // Get WhichId
225
0
    const SfxItemPropertyMapEntry* pEntry = m_aMap.getByName( rName );
226
0
    if( !pEntry || !pEntry->nWID )
227
0
    {
228
0
        throw UnknownPropertyException(rName);
229
0
    }
230
0
    sal_uInt16 nWhich = pEntry->nWID;
231
232
    // Get item state
233
0
    SfxItemState eState = rSet.GetItemState(nWhich, false);
234
    // Return item value as UnoAny
235
0
    if(eState == SfxItemState::DEFAULT)
236
0
        eRet = PropertyState_DEFAULT_VALUE;
237
0
    else if(eState < SfxItemState::DEFAULT)
238
0
        eRet = PropertyState_AMBIGUOUS_VALUE;
239
0
    return eRet;
240
0
}
241
242
rtl::Reference<SfxItemPropertySetInfo> const & SfxItemPropertySet::getPropertySetInfo() const
243
17.9k
{
244
17.9k
    if( !m_xInfo.is() )
245
87
        m_xInfo = new SfxItemPropertySetInfo( m_aMap );
246
17.9k
    return m_xInfo;
247
17.9k
}
248
249
SfxItemPropertySetInfo::SfxItemPropertySetInfo(const SfxItemPropertyMap &rMap )
250
159
    : m_aOwnMap( rMap )
251
159
{
252
159
}
253
254
SfxItemPropertySetInfo::SfxItemPropertySetInfo(std::span<const SfxItemPropertyMapEntry> pEntries )
255
2
    : m_aOwnMap( pEntries )
256
2
{
257
2
}
258
259
Sequence< Property > SAL_CALL SfxItemPropertySetInfo::getProperties(  )
260
46.3k
{
261
46.3k
    return m_aOwnMap.getProperties();
262
46.3k
}
263
264
SfxItemPropertySetInfo::~SfxItemPropertySetInfo()
265
161
{
266
161
}
267
268
Property SAL_CALL SfxItemPropertySetInfo::getPropertyByName( const OUString& rName )
269
0
{
270
0
    return m_aOwnMap.getPropertyByName( rName );
271
0
}
272
273
sal_Bool SAL_CALL SfxItemPropertySetInfo::hasPropertyByName( const OUString& rName )
274
2.19M
{
275
2.19M
    return m_aOwnMap.hasPropertyByName( rName );
276
2.19M
}
277
278
SfxExtItemPropertySetInfo::SfxExtItemPropertySetInfo( std::span<const SfxItemPropertyMapEntry> pEntries,
279
                                                      const Sequence<Property>& rPropSeq )
280
18.8k
{
281
18.8k
    maMap.reserve(pEntries.size() + rPropSeq.getLength());
282
18.8k
    for (const auto & rEntry : pEntries )
283
500k
    {
284
500k
        assert(!rEntry.aName.isEmpty() && "empty name? might be something left an empty entry at the end of this array");
285
500k
        maMap.insert( rEntry );
286
500k
    }
287
18.8k
    for( const auto & rProp : rPropSeq )
288
2.73M
    {
289
2.73M
        SfxItemPropertyMapEntry aTemp(
290
2.73M
            rProp.Name,
291
2.73M
            sal::static_int_cast< sal_Int16 >( rProp.Handle ), //nWID
292
2.73M
            rProp.Type, //aType
293
2.73M
            rProp.Attributes,
294
2.73M
            0); //nFlags
295
2.73M
        maMap.insert( aTemp );
296
2.73M
    }
297
18.8k
}
298
299
SfxExtItemPropertySetInfo::~SfxExtItemPropertySetInfo()
300
18.8k
{
301
18.8k
}
302
303
Sequence< Property > SAL_CALL SfxExtItemPropertySetInfo::getProperties(  )
304
0
{
305
0
    if( !m_aPropSeq.hasElements() )
306
0
    {
307
0
        m_aPropSeq.realloc( maMap.size() );
308
0
        beans::Property* pPropArray = m_aPropSeq.getArray();
309
0
        sal_uInt32 n = 0;
310
0
        for( const SfxItemPropertyMapEntry& rEntry : maMap )
311
0
        {
312
0
            pPropArray[n].Name = rEntry.aName;
313
0
            pPropArray[n].Handle = rEntry.nWID;
314
0
            pPropArray[n].Type = rEntry.aType;
315
0
            pPropArray[n].Attributes =
316
0
                sal::static_int_cast< sal_Int16 >(rEntry.nFlags);
317
0
            n++;
318
0
        }
319
0
    }
320
321
0
    return m_aPropSeq;
322
0
}
323
324
Property SAL_CALL SfxExtItemPropertySetInfo::getPropertyByName( const OUString& rPropertyName )
325
0
{
326
0
    const SfxItemPropertyMapEntry* pEntry = getByName(rPropertyName);
327
0
    if( !pEntry )
328
0
        throw UnknownPropertyException(rPropertyName);
329
0
    beans::Property aProp;
330
0
    aProp.Name = rPropertyName;
331
0
    aProp.Handle = pEntry->nWID;
332
0
    aProp.Type = pEntry->aType;
333
0
    aProp.Attributes = sal::static_int_cast< sal_Int16 >(pEntry->nFlags);
334
0
    return aProp;
335
0
}
336
337
sal_Bool SAL_CALL SfxExtItemPropertySetInfo::hasPropertyByName( const OUString& rPropertyName )
338
942k
{
339
942k
    return getByName(rPropertyName) != nullptr;
340
942k
}
341
342
const SfxItemPropertyMapEntry* SfxExtItemPropertySetInfo::getByName( std::u16string_view rName ) const
343
942k
{
344
942k
    struct Compare
345
942k
    {
346
942k
        bool operator() ( const SfxItemPropertyMapEntry& lhs, std::u16string_view rhs ) const
347
7.50M
        {
348
7.50M
            return lhs.aName < rhs;
349
7.50M
        }
350
942k
        bool operator() ( std::u16string_view lhs, const SfxItemPropertyMapEntry& rhs ) const
351
942k
        {
352
942k
            return lhs < rhs.aName;
353
942k
        }
354
942k
    };
355
942k
    auto it = std::lower_bound(maMap.begin(), maMap.end(), rName, Compare());
356
942k
    if (it == maMap.end() || Compare()(rName, *it))
357
103k
        return nullptr;
358
839k
    return &*it;
359
942k
}
360
361
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */