Coverage Report

Created: 2026-11-06 11:29

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
69
    {
47
69
    }
48
49
    const XMLPropertyHandler* OControlPropertyHandlerFactory::GetPropertyHandler(sal_Int32 _nType) const
50
2.07k
    {
51
2.07k
        const XMLPropertyHandler* pHandler = nullptr;
52
53
2.07k
        switch (_nType)
54
2.07k
        {
55
69
            case XML_TYPE_TEXT_ALIGN:
56
69
                if (!m_pTextAlignHandler)
57
69
                    m_pTextAlignHandler = std::make_unique<XMLConstantsPropertyHandler>(aTextAlignMap, XML_TOKEN_INVALID );
58
69
                pHandler = m_pTextAlignHandler.get();
59
69
                break;
60
61
69
            case XML_TYPE_CONTROL_BORDER:
62
69
                if (!m_pControlBorderStyleHandler)
63
69
                    m_pControlBorderStyleHandler = std::make_unique<OControlBorderHandler>( OControlBorderHandler::STYLE );
64
69
                pHandler = m_pControlBorderStyleHandler.get();
65
69
                break;
66
67
69
            case XML_TYPE_CONTROL_BORDER_COLOR:
68
69
                if ( !m_pControlBorderColorHandler )
69
69
                    m_pControlBorderColorHandler = std::make_unique<OControlBorderHandler>( OControlBorderHandler::COLOR );
70
69
                pHandler = m_pControlBorderColorHandler.get();
71
69
                break;
72
73
69
            case XML_TYPE_ROTATION_ANGLE:
74
69
                if (!m_pRotationAngleHandler)
75
69
                    m_pRotationAngleHandler = std::make_unique<ORotationAngleHandler>();
76
69
                pHandler = m_pRotationAngleHandler.get();
77
69
                break;
78
79
69
            case XML_TYPE_FONT_WIDTH:
80
69
                if (!m_pFontWidthHandler)
81
69
                    m_pFontWidthHandler = std::make_unique<OFontWidthHandler>();
82
69
                pHandler = m_pFontWidthHandler.get();
83
69
                break;
84
85
69
            case XML_TYPE_CONTROL_TEXT_EMPHASIZE:
86
69
                if (!m_pFontEmphasisHandler)
87
69
                    m_pFontEmphasisHandler = std::make_unique<XMLConstantsPropertyHandler>( aFontEmphasisMap, XML_NONE );
88
69
                pHandler = m_pFontEmphasisHandler.get();
89
69
                break;
90
91
69
            case XML_TYPE_TEXT_FONT_RELIEF:
92
69
                if (!m_pFontReliefHandler)
93
69
                    m_pFontReliefHandler = std::make_unique<XMLConstantsPropertyHandler>( aFontReliefMap, XML_NONE );
94
69
                pHandler = m_pFontReliefHandler.get();
95
69
                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.07k
        }
106
107
2.07k
        if (!pHandler)
108
1.58k
            pHandler = XMLPropertyHandlerFactory::GetPropertyHandler(_nType);
109
2.07k
        return pHandler;
110
2.07k
    }
111
112
    //= OControlTextEmphasisHandler
113
    OControlTextEmphasisHandler::OControlTextEmphasisHandler()
114
17.0k
    {
115
17.0k
    }
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
14
    {
145
14
        bool bSuccess = true;
146
14
        sal_uInt16 nEmphasis = awt::FontEmphasisMark::NONE;
147
148
14
        bool bBelow = false;
149
14
        bool bHasPos = false, bHasType = false;
150
151
14
        std::u16string_view sToken;
152
14
        SvXMLTokenEnumerator aTokenEnum(_rStrImpValue);
153
28
        while (aTokenEnum.getNextToken(sToken))
154
14
        {
155
14
            if (!bHasPos)
156
14
            {
157
14
                if (IsXMLToken(sToken, XML_ABOVE))
158
0
                {
159
0
                    bBelow = false;
160
0
                    bHasPos = true;
161
0
                }
162
14
                else if (IsXMLToken(sToken, XML_BELOW))
163
0
                {
164
0
                    bBelow = true;
165
0
                    bHasPos = true;
166
0
                }
167
14
            }
168
14
            if (!bHasType)
169
14
            {
170
14
                if (SvXMLUnitConverter::convertEnum(nEmphasis, sToken, aFontEmphasisMap))
171
14
                {
172
14
                    bHasType = true;
173
14
                }
174
0
                else
175
0
                {
176
0
                    bSuccess = false;
177
0
                    break;
178
0
                }
179
14
            }
180
14
        }
181
182
14
        if (bSuccess)
183
14
        {
184
14
            nEmphasis |= bBelow ? awt::FontEmphasisMark::BELOW : awt::FontEmphasisMark::ABOVE;
185
14
            _rValue <<= nEmphasis;
186
14
        }
187
188
14
        return bSuccess;
189
14
    }
190
191
    //= OControlBorderHandlerBase
192
    OControlBorderHandler::OControlBorderHandler( const OControlBorderHandler::BorderFacet _eFacet )
193
34.1k
        :m_eFacet( _eFacet )
194
34.1k
    {
195
34.1k
    }
196
197
    bool OControlBorderHandler::importXML( const OUString& _rStrImpValue, Any& _rValue, const SvXMLUnitConverter& ) const
198
1.78k
    {
199
1.78k
        std::u16string_view sToken;
200
1.78k
        SvXMLTokenEnumerator aTokens(_rStrImpValue);
201
202
1.78k
        sal_uInt16 nStyle = 1;
203
204
3.57k
        while   (   aTokens.getNextToken(sToken)    // have a new token
205
3.11k
                &&  (!sToken.empty())       // really have a new token
206
1.78k
                )
207
3.11k
        {
208
            // try interpreting the token as border style
209
3.11k
            if ( m_eFacet == STYLE )
210
1.33k
            {
211
                // is it a valid enum value?
212
1.33k
                if ( SvXMLUnitConverter::convertEnum( nStyle, sToken, aBorderTypeMap ) )
213
886
                {
214
886
                    _rValue <<= nStyle;
215
886
                    return true;
216
886
                }
217
1.33k
            }
218
219
            // try interpreting it as color value
220
2.22k
            if ( m_eFacet == COLOR )
221
1.77k
            {
222
1.77k
                sal_Int32 nColor(0);
223
1.77k
                if (::sax::Converter::convertColor( nColor, sToken ))
224
439
                {
225
439
                    _rValue <<= nColor;
226
439
                    return true;
227
439
                }
228
1.77k
            }
229
2.22k
        }
230
231
461
        return false;
232
1.78k
    }
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
69
    {
273
69
    }
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
69
    {
303
69
    }
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.0k
        :XMLConstantsPropertyHandler( aScaleModeMap, XML_STRETCH )
337
17.0k
    {
338
17.0k
    }
339
340
}   // namespace xmloff
341
342
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */