Coverage Report

Created: 2026-03-31 11:00

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libreoffice/sc/source/ui/unoobj/defltuno.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 <editeng/memberids.h>
21
#include <svl/hint.hxx>
22
#include <svl/itemprop.hxx>
23
#include <vcl/svapp.hxx>
24
#include <i18nlangtag/languagetag.hxx>
25
26
#include <scitems.hxx>
27
#include <defltuno.hxx>
28
#include <miscuno.hxx>
29
#include <docsh.hxx>
30
#include <docpool.hxx>
31
#include <unonames.hxx>
32
#include <docoptio.hxx>
33
34
#include <limits>
35
36
class SvxFontItem;
37
using namespace ::com::sun::star;
38
39
static std::span<const SfxItemPropertyMapEntry> lcl_GetDocDefaultsMap()
40
1.06k
{
41
1.06k
    static const SfxItemPropertyMapEntry aDocDefaultsMap_Impl[] =
42
1.06k
    {
43
1.06k
        { SC_UNONAME_CFCHARS,  ATTR_FONT,          cppu::UnoType<sal_Int16>::get(),        0, MID_FONT_CHAR_SET },
44
1.06k
        { SC_UNO_CJK_CFCHARS,  ATTR_CJK_FONT,      cppu::UnoType<sal_Int16>::get(),        0, MID_FONT_CHAR_SET },
45
1.06k
        { SC_UNO_CTL_CFCHARS,  ATTR_CTL_FONT,      cppu::UnoType<sal_Int16>::get(),        0, MID_FONT_CHAR_SET },
46
1.06k
        { SC_UNONAME_CFFAMIL,  ATTR_FONT,          cppu::UnoType<sal_Int16>::get(),        0, MID_FONT_FAMILY },
47
1.06k
        { SC_UNO_CJK_CFFAMIL,  ATTR_CJK_FONT,      cppu::UnoType<sal_Int16>::get(),        0, MID_FONT_FAMILY },
48
1.06k
        { SC_UNO_CTL_CFFAMIL,  ATTR_CTL_FONT,      cppu::UnoType<sal_Int16>::get(),        0, MID_FONT_FAMILY },
49
1.06k
        { SC_UNONAME_CFNAME,   ATTR_FONT,          cppu::UnoType<OUString>::get(),    0, MID_FONT_FAMILY_NAME },
50
1.06k
        { SC_UNO_CJK_CFNAME,   ATTR_CJK_FONT,      cppu::UnoType<OUString>::get(),    0, MID_FONT_FAMILY_NAME },
51
1.06k
        { SC_UNO_CTL_CFNAME,   ATTR_CTL_FONT,      cppu::UnoType<OUString>::get(),    0, MID_FONT_FAMILY_NAME },
52
1.06k
        { SC_UNONAME_CFPITCH,  ATTR_FONT,          cppu::UnoType<sal_Int16>::get(),        0, MID_FONT_PITCH },
53
1.06k
        { SC_UNO_CJK_CFPITCH,  ATTR_CJK_FONT,      cppu::UnoType<sal_Int16>::get(),        0, MID_FONT_PITCH },
54
1.06k
        { SC_UNO_CTL_CFPITCH,  ATTR_CTL_FONT,      cppu::UnoType<sal_Int16>::get(),        0, MID_FONT_PITCH },
55
1.06k
        { SC_UNONAME_CFSTYLE,  ATTR_FONT,          cppu::UnoType<OUString>::get(),    0, MID_FONT_STYLE_NAME },
56
1.06k
        { SC_UNO_CJK_CFSTYLE,  ATTR_CJK_FONT,      cppu::UnoType<OUString>::get(),    0, MID_FONT_STYLE_NAME },
57
1.06k
        { SC_UNO_CTL_CFSTYLE,  ATTR_CTL_FONT,      cppu::UnoType<OUString>::get(),    0, MID_FONT_STYLE_NAME },
58
1.06k
        { SC_UNONAME_CLOCAL,   ATTR_FONT_LANGUAGE, cppu::UnoType<lang::Locale>::get(),     0, MID_LANG_LOCALE },
59
1.06k
        { SC_UNO_CJK_CLOCAL,   ATTR_CJK_FONT_LANGUAGE, cppu::UnoType<lang::Locale>::get(), 0, MID_LANG_LOCALE },
60
1.06k
        { SC_UNO_CTL_CLOCAL,   ATTR_CTL_FONT_LANGUAGE, cppu::UnoType<lang::Locale>::get(), 0, MID_LANG_LOCALE },
61
1.06k
        { SC_UNONAME_CHEIGHT,  ATTR_FONT_HEIGHT,     cppu::UnoType<float>::get(), 0, MID_FONTHEIGHT | CONVERT_TWIPS },
62
1.06k
        { SC_UNO_CJK_CHEIGHT,  ATTR_CJK_FONT_HEIGHT, cppu::UnoType<float>::get(), 0, MID_FONTHEIGHT | CONVERT_TWIPS },
63
1.06k
        { SC_UNO_CTL_CHEIGHT,  ATTR_CTL_FONT_HEIGHT, cppu::UnoType<float>::get(), 0, MID_FONTHEIGHT | CONVERT_TWIPS },
64
1.06k
        { SC_UNO_STANDARDDEC,              0,      cppu::UnoType<sal_Int16>::get(),        0, 0 },
65
1.06k
        { SC_UNO_TABSTOPDIS,               0,      cppu::UnoType<sal_Int32>::get(),        0, 0 },
66
1.06k
        { SC_UNONAME_WRAP,                 0,      cppu::UnoType<sal_Int16>::get(),        0, 0 },
67
1.06k
    };
68
1.06k
    return aDocDefaultsMap_Impl;
69
1.06k
}
70
71
using sc::TwipsToEvenHMM;
72
73
SC_SIMPLE_SERVICE_INFO( ScDocDefaultsObj, u"ScDocDefaultsObj"_ustr, u"com.sun.star.sheet.Defaults"_ustr )
74
75
ScDocDefaultsObj::ScDocDefaultsObj(ScDocShell* pDocSh) :
76
1.06k
    pDocShell( pDocSh ),
77
1.06k
    aPropertyMap(lcl_GetDocDefaultsMap())
78
1.06k
{
79
1.06k
    pDocShell->GetDocument().AddUnoObject(*this);
80
1.06k
}
81
82
ScDocDefaultsObj::~ScDocDefaultsObj()
83
1.06k
{
84
1.06k
    SolarMutexGuard g;
85
86
1.06k
    if (pDocShell)
87
1.06k
        pDocShell->GetDocument().RemoveUnoObject(*this);
88
1.06k
}
89
90
void ScDocDefaultsObj::Notify( SfxBroadcaster&, const SfxHint& rHint )
91
0
{
92
0
    if ( rHint.GetId() == SfxHintId::Dying )
93
0
    {
94
0
        pDocShell = nullptr;       // document gone
95
0
    }
96
0
}
97
98
void ScDocDefaultsObj::ItemsChanged()
99
6.97k
{
100
6.97k
    if (pDocShell)
101
6.97k
    {
102
        //! if not in XML import, adjust row heights
103
6.97k
        const auto & rDoc = pDocShell->GetDocument();
104
6.97k
        pDocShell->PostPaint(ScRange(0, 0, 0, rDoc.MaxCol(), rDoc.MaxRow(), MAXTAB), PaintPartFlags::Grid);
105
6.97k
    }
106
6.97k
}
107
108
// XPropertySet
109
110
uno::Reference<beans::XPropertySetInfo> SAL_CALL ScDocDefaultsObj::getPropertySetInfo()
111
1.06k
{
112
1.06k
    SolarMutexGuard aGuard;
113
1.06k
    static uno::Reference<beans::XPropertySetInfo> aRef = new SfxItemPropertySetInfo(
114
1.06k
                                                                        aPropertyMap );
115
1.06k
    return aRef;
116
1.06k
}
117
118
void SAL_CALL ScDocDefaultsObj::setPropertyValue(
119
                        const OUString& aPropertyName, const uno::Any& aValue )
120
10.6k
{
121
10.6k
    SolarMutexGuard aGuard;
122
123
10.6k
    if ( !pDocShell )
124
0
        throw uno::RuntimeException();
125
126
10.6k
    const SfxItemPropertyMapEntry* pEntry = aPropertyMap.getByName( aPropertyName );
127
10.6k
    if ( !pEntry )
128
0
        throw beans::UnknownPropertyException(aPropertyName);
129
10.6k
    if(!pEntry->nWID)
130
597
    {
131
597
        if(aPropertyName ==SC_UNO_STANDARDDEC)
132
0
        {
133
0
            ScDocument& rDoc = pDocShell->GetDocument();
134
0
            ScDocOptions aDocOpt(rDoc.GetDocOptions());
135
0
            sal_Int16 nValue = 0;
136
0
            if (aValue >>= nValue)
137
0
            {
138
0
                aDocOpt.SetStdPrecision(static_cast<sal_uInt16> (nValue));
139
0
                rDoc.SetDocOptions(aDocOpt);
140
0
            }
141
0
        }
142
597
        else if(aPropertyName == SC_UNONAME_WRAP)
143
0
        {
144
0
            ScDocument& rDoc = pDocShell->GetDocument();
145
0
            ScDocOptions aDocOpt(rDoc.GetDocOptions());
146
0
            bool bValue = false;
147
148
0
            aValue >>= bValue;
149
0
            if (bValue)
150
0
            {
151
                // ODS documents converted from XLSX:
152
                // if wrap option is enabled, it means the original XLSX document had some cells with line breaks.
153
                // we need to keep the same behavior in ODS documents too.
154
0
                aDocOpt.SetIgnoreLineBreaks(true);
155
0
                rDoc.SetDocOptions(aDocOpt);
156
0
            }
157
0
        }
158
597
        else if (aPropertyName == SC_UNO_TABSTOPDIS)
159
597
        {
160
597
            ScDocument& rDoc = pDocShell->GetDocument();
161
597
            ScDocOptions aDocOpt(rDoc.GetDocOptions());
162
597
            sal_Int32 nValue = 0;
163
597
            if (aValue >>= nValue)
164
597
            {
165
597
                aDocOpt.SetTabDistance(o3tl::toTwips(nValue, o3tl::Length::mm100));
166
597
                rDoc.SetDocOptions(aDocOpt);
167
597
            }
168
597
        }
169
597
    }
170
10.0k
    else if ( pEntry->nWID == ATTR_FONT_LANGUAGE ||
171
9.51k
              pEntry->nWID == ATTR_CJK_FONT_LANGUAGE ||
172
7.95k
              pEntry->nWID == ATTR_CTL_FONT_LANGUAGE )
173
3.09k
    {
174
        //  for getPropertyValue the PoolDefaults are sufficient,
175
        //  but setPropertyValue has to be handled differently
176
177
3.09k
        lang::Locale aLocale;
178
3.09k
        if ( aValue >>= aLocale )
179
3.09k
        {
180
3.09k
            LanguageType eNew;
181
3.09k
            if (!aLocale.Language.isEmpty() || !aLocale.Country.isEmpty())
182
3.08k
                eNew = LanguageTag::convertToLanguageType( aLocale, false);
183
5
            else
184
5
                eNew = LANGUAGE_NONE;
185
186
3.09k
            ScDocument& rDoc = pDocShell->GetDocument();
187
3.09k
            LanguageType eLatin, eCjk, eCtl;
188
3.09k
            rDoc.GetLanguage( eLatin, eCjk, eCtl );
189
190
3.09k
            if ( pEntry->nWID == ATTR_CJK_FONT_LANGUAGE )
191
1.56k
                eCjk = eNew;
192
1.53k
            else if ( pEntry->nWID == ATTR_CTL_FONT_LANGUAGE )
193
985
                eCtl = eNew;
194
545
            else
195
545
                eLatin = eNew;
196
197
3.09k
            rDoc.SetLanguage( eLatin, eCjk, eCtl );
198
3.09k
        }
199
3.09k
    }
200
6.97k
    else
201
6.97k
    {
202
6.97k
        ScDocumentPool* pPool = pDocShell->GetDocument().GetPool();
203
6.97k
        std::unique_ptr<SfxPoolItem> pNewItem(pPool->GetUserOrPoolDefaultItem(pEntry->nWID).Clone());
204
205
6.97k
        if( !pNewItem->PutValue( aValue, pEntry->nMemberId ) )
206
0
            throw lang::IllegalArgumentException();
207
208
6.97k
        pPool->SetUserDefaultItem( *pNewItem );
209
210
6.97k
        ItemsChanged();
211
6.97k
    }
212
10.6k
}
213
214
uno::Any SAL_CALL ScDocDefaultsObj::getPropertyValue( const OUString& aPropertyName )
215
0
{
216
    //  use pool default if set
217
218
0
    SolarMutexGuard aGuard;
219
220
0
    if ( !pDocShell )
221
0
        throw uno::RuntimeException();
222
223
0
    uno::Any aRet;
224
0
    const SfxItemPropertyMapEntry* pEntry = aPropertyMap.getByName( aPropertyName );
225
0
    if ( !pEntry )
226
0
        throw beans::UnknownPropertyException(aPropertyName);
227
228
0
    if (!pEntry->nWID)
229
0
    {
230
0
        if(aPropertyName == SC_UNO_STANDARDDEC)
231
0
        {
232
0
            ScDocument& rDoc = pDocShell->GetDocument();
233
0
            const ScDocOptions& aDocOpt = rDoc.GetDocOptions();
234
0
            sal_uInt16 nPrec = aDocOpt.GetStdPrecision();
235
            // the max value of unsigned 16-bit integer is used as the flag
236
            // value for unlimited precision, c.f.
237
            // SvNumberFormatter::UNLIMITED_PRECISION.
238
0
            if (nPrec <= ::std::numeric_limits<sal_Int16>::max())
239
0
                aRet <<= static_cast<sal_Int16> (nPrec);
240
0
        }
241
0
        else if(aPropertyName == SC_UNONAME_WRAP)
242
0
        {
243
0
            ScDocument& rDoc = pDocShell->GetDocument();
244
0
            const ScDocOptions& aDocOpt = rDoc.GetDocOptions();
245
246
0
            bool bWrap = aDocOpt.IsIgnoreLineBreaks();
247
0
            aRet <<=  bWrap;
248
0
        }
249
0
        else if (aPropertyName == SC_UNO_TABSTOPDIS)
250
0
        {
251
0
            ScDocument& rDoc = pDocShell->GetDocument();
252
0
            const ScDocOptions& aDocOpt = rDoc.GetDocOptions();
253
0
            sal_Int32 nValue (TwipsToEvenHMM(aDocOpt.GetTabDistance()));
254
0
            aRet <<= nValue;
255
0
        }
256
0
    }
257
0
    else
258
0
    {
259
0
        ScDocumentPool* pPool = pDocShell->GetDocument().GetPool();
260
0
        const SfxPoolItem& rItem = pPool->GetUserOrPoolDefaultItem( pEntry->nWID );
261
0
        rItem.QueryValue( aRet, pEntry->nMemberId );
262
0
    }
263
0
    return aRet;
264
0
}
265
266
SC_IMPL_DUMMY_PROPERTY_LISTENER( ScDocDefaultsObj )
267
268
// XPropertyState
269
270
beans::PropertyState SAL_CALL ScDocDefaultsObj::getPropertyState( const OUString& aPropertyName )
271
0
{
272
0
    SolarMutexGuard aGuard;
273
274
0
    if ( !pDocShell )
275
0
        throw uno::RuntimeException();
276
277
0
    const SfxItemPropertyMapEntry* pEntry = aPropertyMap.getByName( aPropertyName );
278
0
    if ( !pEntry )
279
0
        throw beans::UnknownPropertyException(aPropertyName);
280
281
0
    beans::PropertyState eRet = beans::PropertyState_DEFAULT_VALUE;
282
283
0
    sal_uInt16 nWID = pEntry->nWID;
284
0
    if ( nWID == ATTR_FONT || nWID == ATTR_CJK_FONT || nWID == ATTR_CTL_FONT || !nWID )
285
0
    {
286
        //  static default for font is system-dependent,
287
        //  so font default is always treated as "direct value".
288
289
0
        eRet = beans::PropertyState_DIRECT_VALUE;
290
0
    }
291
0
    else
292
0
    {
293
        //  check if pool default is set
294
295
0
        ScDocumentPool* pPool = pDocShell->GetDocument().GetPool();
296
0
        if ( pPool->GetUserDefaultItem( nWID ) != nullptr )
297
0
            eRet = beans::PropertyState_DIRECT_VALUE;
298
0
    }
299
300
0
    return eRet;
301
0
}
302
303
uno::Sequence<beans::PropertyState> SAL_CALL ScDocDefaultsObj::getPropertyStates(
304
                            const uno::Sequence<OUString>& aPropertyNames )
305
0
{
306
    //  the simple way: call getPropertyState
307
308
0
    SolarMutexGuard aGuard;
309
0
    uno::Sequence<beans::PropertyState> aRet(aPropertyNames.getLength());
310
0
    std::transform(aPropertyNames.begin(), aPropertyNames.end(), aRet.getArray(),
311
0
        [this](const OUString& rName) -> beans::PropertyState { return getPropertyState(rName); });
312
0
    return aRet;
313
0
}
314
315
void SAL_CALL ScDocDefaultsObj::setPropertyToDefault( const OUString& aPropertyName )
316
0
{
317
0
    SolarMutexGuard aGuard;
318
319
0
    if ( !pDocShell )
320
0
        throw uno::RuntimeException();
321
322
0
    const SfxItemPropertyMapEntry* pEntry = aPropertyMap.getByName( aPropertyName );
323
0
    if ( !pEntry )
324
0
        throw beans::UnknownPropertyException(aPropertyName);
325
326
0
    if (pEntry->nWID)
327
0
    {
328
0
        ScDocumentPool* pPool = pDocShell->GetDocument().GetPool();
329
0
        pPool->ResetUserDefaultItem( pEntry->nWID );
330
331
0
        ItemsChanged();
332
0
    }
333
0
}
334
335
uno::Any SAL_CALL ScDocDefaultsObj::getPropertyDefault( const OUString& aPropertyName )
336
0
{
337
    //  always use static default
338
339
0
    SolarMutexGuard aGuard;
340
341
0
    if ( !pDocShell )
342
0
        throw uno::RuntimeException();
343
344
0
    const SfxItemPropertyMapEntry* pEntry = aPropertyMap.getByName( aPropertyName );
345
0
    if ( !pEntry )
346
0
        throw beans::UnknownPropertyException(aPropertyName);
347
348
0
    uno::Any aRet;
349
0
    if (pEntry->nWID)
350
0
    {
351
0
        ScDocumentPool* pPool = pDocShell->GetDocument().GetPool();
352
0
        const SfxPoolItem* pItem = pPool->GetPoolDefaultItem( pEntry->nWID );
353
0
        if (pItem)
354
0
            pItem->QueryValue( aRet, pEntry->nMemberId );
355
0
    }
356
0
    return aRet;
357
0
}
358
359
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */