Coverage Report

Created: 2026-08-14 10:22

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libreoffice/xmloff/source/forms/controlpropertyhdl.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 <xmloff/controlpropertyhdl.hxx>
21
22
#include <com/sun/star/util/MeasureUnit.hpp>
23
#include <com/sun/star/awt/FontEmphasisMark.hpp>
24
25
#include <sax/tools/converter.hxx>
26
27
#include <xmloff/xmltypes.hxx>
28
#include <xmloff/NamedBoolPropertyHdl.hxx>
29
#include "formenums.hxx"
30
#include <xmloff/xmluconv.hxx>
31
#include <xmloff/xmltoken.hxx>
32
#include <rtl/ustrbuf.hxx>
33
#include <xmloff/XMLConstantsPropertyHandler.hxx>
34
35
namespace xmloff
36
{
37
38
    using namespace ::com::sun::star;
39
    using namespace ::com::sun::star::uno;
40
    using namespace ::com::sun::star::awt;
41
    using namespace ::com::sun::star::beans;
42
    using namespace ::xmloff::token;
43
44
    //= OControlPropertyHandlerFactory
45
    OControlPropertyHandlerFactory::OControlPropertyHandlerFactory()
46
75
    {
47
75
    }
48
49
    const XMLPropertyHandler* OControlPropertyHandlerFactory::GetPropertyHandler(sal_Int32 _nType) const
50
2.25k
    {
51
2.25k
        const XMLPropertyHandler* pHandler = nullptr;
52
53
2.25k
        switch (_nType)
54
2.25k
        {
55
75
            case XML_TYPE_TEXT_ALIGN:
56
75
                if (!m_pTextAlignHandler)
57
75
                    m_pTextAlignHandler = std::make_unique<XMLConstantsPropertyHandler>(aTextAlignMap, XML_TOKEN_INVALID );
58
75
                pHandler = m_pTextAlignHandler.get();
59
75
                break;
60
61
75
            case XML_TYPE_CONTROL_BORDER:
62
75
                if (!m_pControlBorderStyleHandler)
63
75
                    m_pControlBorderStyleHandler = std::make_unique<OControlBorderHandler>( OControlBorderHandler::STYLE );
64
75
                pHandler = m_pControlBorderStyleHandler.get();
65
75
                break;
66
67
75
            case XML_TYPE_CONTROL_BORDER_COLOR:
68
75
                if ( !m_pControlBorderColorHandler )
69
75
                    m_pControlBorderColorHandler = std::make_unique<OControlBorderHandler>( OControlBorderHandler::COLOR );
70
75
                pHandler = m_pControlBorderColorHandler.get();
71
75
                break;
72
73
75
            case XML_TYPE_ROTATION_ANGLE:
74
75
                if (!m_pRotationAngleHandler)
75
75
                    m_pRotationAngleHandler = std::make_unique<ORotationAngleHandler>();
76
75
                pHandler = m_pRotationAngleHandler.get();
77
75
                break;
78
79
75
            case XML_TYPE_FONT_WIDTH:
80
75
                if (!m_pFontWidthHandler)
81
75
                    m_pFontWidthHandler = std::make_unique<OFontWidthHandler>();
82
75
                pHandler = m_pFontWidthHandler.get();
83
75
                break;
84
85
75
            case XML_TYPE_CONTROL_TEXT_EMPHASIZE:
86
75
                if (!m_pFontEmphasisHandler)
87
75
                    m_pFontEmphasisHandler = std::make_unique<XMLConstantsPropertyHandler>( aFontEmphasisMap, XML_NONE );
88
75
                pHandler = m_pFontEmphasisHandler.get();
89
75
                break;
90
91
75
            case XML_TYPE_TEXT_FONT_RELIEF:
92
75
                if (!m_pFontReliefHandler)
93
75
                    m_pFontReliefHandler = std::make_unique<XMLConstantsPropertyHandler>( aFontReliefMap, XML_NONE );
94
75
                pHandler = m_pFontReliefHandler.get();
95
75
                break;
96
0
            case XML_TYPE_TEXT_LINE_MODE:
97
0
                if (!m_pTextLineModeHandler)
98
0
                {
99
0
                    m_pTextLineModeHandler = std::make_unique<XMLNamedBoolPropertyHdl>(
100
0
                            ::xmloff::token::XML_SKIP_WHITE_SPACE,
101
0
                            ::xmloff::token::XML_CONTINUOUS);
102
0
                }
103
0
                pHandler = m_pTextLineModeHandler.get();
104
0
                break;
105
2.25k
        }
106
107
2.25k
        if (!pHandler)
108
1.72k
            pHandler = XMLPropertyHandlerFactory::GetPropertyHandler(_nType);
109
2.25k
        return pHandler;
110
2.25k
    }
111
112
    //= OControlTextEmphasisHandler
113
    OControlTextEmphasisHandler::OControlTextEmphasisHandler()
114
17.8k
    {
115
17.8k
    }
116
117
    bool OControlTextEmphasisHandler::exportXML( OUString& _rStrExpValue, const Any& _rValue, const SvXMLUnitConverter& ) const
118
0
    {
119
0
        bool bSuccess = false;
120
0
        sal_Int16 nFontEmphasis = sal_Int16();
121
0
        if (_rValue >>= nFontEmphasis)
122
0
        {
123
            // the type
124
0
            sal_uInt16 nType = nFontEmphasis & ~(awt::FontEmphasisMark::ABOVE | awt::FontEmphasisMark::BELOW);
125
            // the position of the mark
126
0
            bool bBelow = 0 != (nFontEmphasis & awt::FontEmphasisMark::BELOW);
127
128
            // convert
129
0
            OUStringBuffer aReturn;
130
0
            bSuccess = SvXMLUnitConverter::convertEnum(aReturn, nType, aFontEmphasisMap, XML_NONE);
131
0
            if (bSuccess)
132
0
            {
133
0
                aReturn.append( ' ' );
134
0
                aReturn.append( GetXMLToken(bBelow ? XML_BELOW : XML_ABOVE) );
135
136
0
                _rStrExpValue = aReturn.makeStringAndClear();
137
0
            }
138
0
        }
139
140
0
        return bSuccess;
141
0
    }
142
143
    bool OControlTextEmphasisHandler::importXML( const OUString& _rStrImpValue, Any& _rValue, const SvXMLUnitConverter& ) const
144
17
    {
145
17
        bool bSuccess = true;
146
17
        sal_uInt16 nEmphasis = awt::FontEmphasisMark::NONE;
147
148
17
        bool bBelow = false;
149
17
        bool bHasPos = false, bHasType = false;
150
151
17
        std::u16string_view sToken;
152
17
        SvXMLTokenEnumerator aTokenEnum(_rStrImpValue);
153
34
        while (aTokenEnum.getNextToken(sToken))
154
17
        {
155
17
            if (!bHasPos)
156
17
            {
157
17
                if (IsXMLToken(sToken, XML_ABOVE))
158
0
                {
159
0
                    bBelow = false;
160
0
                    bHasPos = true;
161
0
                }
162
17
                else if (IsXMLToken(sToken, XML_BELOW))
163
0
                {
164
0
                    bBelow = true;
165
0
                    bHasPos = true;
166
0
                }
167
17
            }
168
17
            if (!bHasType)
169
17
            {
170
17
                if (SvXMLUnitConverter::convertEnum(nEmphasis, sToken, aFontEmphasisMap))
171
17
                {
172
17
                    bHasType = true;
173
17
                }
174
0
                else
175
0
                {
176
0
                    bSuccess = false;
177
0
                    break;
178
0
                }
179
17
            }
180
17
        }
181
182
17
        if (bSuccess)
183
17
        {
184
17
            nEmphasis |= bBelow ? awt::FontEmphasisMark::BELOW : awt::FontEmphasisMark::ABOVE;
185
17
            _rValue <<= nEmphasis;
186
17
        }
187
188
17
        return bSuccess;
189
17
    }
190
191
    //= OControlBorderHandlerBase
192
    OControlBorderHandler::OControlBorderHandler( const OControlBorderHandler::BorderFacet _eFacet )
193
35.7k
        :m_eFacet( _eFacet )
194
35.7k
    {
195
35.7k
    }
196
197
    bool OControlBorderHandler::importXML( const OUString& _rStrImpValue, Any& _rValue, const SvXMLUnitConverter& ) const
198
1.74k
    {
199
1.74k
        std::u16string_view sToken;
200
1.74k
        SvXMLTokenEnumerator aTokens(_rStrImpValue);
201
202
1.74k
        sal_uInt16 nStyle = 1;
203
204
3.43k
        while   (   aTokens.getNextToken(sToken)    // have a new token
205
2.95k
                &&  (!sToken.empty())       // really have a new token
206
1.74k
                )
207
2.95k
        {
208
            // try interpreting the token as border style
209
2.95k
            if ( m_eFacet == STYLE )
210
1.28k
            {
211
                // is it a valid enum value?
212
1.28k
                if ( SvXMLUnitConverter::convertEnum( nStyle, sToken, aBorderTypeMap ) )
213
866
                {
214
866
                    _rValue <<= nStyle;
215
866
                    return true;
216
866
                }
217
1.28k
            }
218
219
            // try interpreting it as color value
220
2.09k
            if ( m_eFacet == COLOR )
221
1.67k
            {
222
1.67k
                sal_Int32 nColor(0);
223
1.67k
                if (::sax::Converter::convertColor( nColor, sToken ))
224
401
                {
225
401
                    _rValue <<= nColor;
226
401
                    return true;
227
401
                }
228
1.67k
            }
229
2.09k
        }
230
231
481
        return false;
232
1.74k
    }
233
234
    bool OControlBorderHandler::exportXML( OUString& _rStrExpValue, const Any& _rValue, const SvXMLUnitConverter& ) const
235
0
    {
236
0
        bool bSuccess = false;
237
238
0
        OUStringBuffer aOut;
239
0
        switch ( m_eFacet )
240
0
        {
241
0
        case STYLE:
242
0
        {
243
0
            sal_uInt16 nBorder = 0;
244
0
            bSuccess =  (_rValue >>= nBorder)
245
0
                    &&  SvXMLUnitConverter::convertEnum( aOut, nBorder, aBorderTypeMap );
246
0
        }
247
0
        break;
248
0
        case COLOR:
249
0
        {
250
0
            sal_Int32 nBorderColor = 0;
251
0
            if ( _rValue >>= nBorderColor )
252
0
            {
253
0
                ::sax::Converter::convertColor(aOut, nBorderColor);
254
0
                bSuccess = true;
255
0
            }
256
0
        }
257
0
        break;
258
0
        }   // switch ( m_eFacet )
259
260
0
        if ( !bSuccess )
261
0
            return false;
262
263
0
        if ( !_rStrExpValue.isEmpty() )
264
0
            _rStrExpValue += " ";
265
0
        _rStrExpValue += aOut;
266
267
0
        return true;
268
0
    }
269
270
    //= OFontWidthHandler
271
    OFontWidthHandler::OFontWidthHandler()
272
75
    {
273
75
    }
274
275
    bool OFontWidthHandler::importXML( const OUString& _rStrImpValue, Any& _rValue, const SvXMLUnitConverter& ) const
276
0
    {
277
0
        sal_Int32 nWidth = 0;
278
0
        bool const bSuccess = ::sax::Converter::convertMeasure(
279
0
                nWidth, _rStrImpValue, util::MeasureUnit::POINT);
280
0
        if (bSuccess)
281
0
            _rValue <<= static_cast<sal_Int16>(nWidth);
282
283
0
        return bSuccess;
284
0
    }
285
286
    bool OFontWidthHandler::exportXML( OUString& _rStrExpValue, const Any& _rValue, const SvXMLUnitConverter& ) const
287
0
    {
288
0
        sal_Int16 nWidth = 0;
289
0
        OUStringBuffer aResult;
290
0
        if (_rValue >>= nWidth)
291
0
        {
292
0
            ::sax::Converter::convertMeasure(aResult, nWidth,
293
0
                    util::MeasureUnit::POINT, util::MeasureUnit::POINT);
294
0
        }
295
0
        _rStrExpValue = aResult.makeStringAndClear();
296
297
0
        return !_rStrExpValue.isEmpty();
298
0
    }
299
300
    //= ORotationAngleHandler
301
    ORotationAngleHandler::ORotationAngleHandler()
302
75
    {
303
75
    }
304
305
    bool ORotationAngleHandler::importXML( const OUString& _rStrImpValue, Any& _rValue, const SvXMLUnitConverter& ) const
306
0
    {
307
0
        double fValue;
308
0
        bool const bSucces =
309
0
            ::sax::Converter::convertDouble(fValue, _rStrImpValue);
310
0
        if (bSucces)
311
0
        {
312
0
            fValue *= 10;
313
0
            _rValue <<= static_cast<float>(fValue);
314
0
        }
315
316
0
        return bSucces;
317
0
    }
318
319
    bool ORotationAngleHandler::exportXML( OUString& _rStrExpValue, const Any& _rValue, const SvXMLUnitConverter& ) const
320
0
    {
321
0
        float fAngle = 0;
322
0
        bool bSuccess = (_rValue >>= fAngle);
323
324
0
        if (bSuccess)
325
0
        {
326
0
            OUStringBuffer sValue;
327
0
            ::sax::Converter::convertDouble(sValue, static_cast<double>(fAngle) / 10);
328
0
            _rStrExpValue = sValue.makeStringAndClear();
329
0
        }
330
331
0
        return bSuccess;
332
0
    }
333
334
    //= ImageScaleModeHandler
335
    ImageScaleModeHandler::ImageScaleModeHandler()
336
17.8k
        :XMLConstantsPropertyHandler( aScaleModeMap, XML_STRETCH )
337
17.8k
    {
338
17.8k
    }
339
340
}   // namespace xmloff
341
342
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */