Coverage Report

Created: 2026-03-31 11:00

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libreoffice/xmloff/source/transform/StyleOASISTContext.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 <com/sun/star/xml/sax/XDocumentHandler.hpp>
21
#include <rtl/ustrbuf.hxx>
22
#include <osl/diagnose.h>
23
#include <sax/tools/converter.hxx>
24
#include <xmloff/namespacemap.hxx>
25
#include <xmloff/xmltoken.hxx>
26
#include <xmloff/xmlnamespace.hxx>
27
#include "PropType.hxx"
28
#include "DeepTContext.hxx"
29
#include "TransformerBase.hxx"
30
#include "TransformerActions.hxx"
31
#include "ActionMapTypesOASIS.hxx"
32
#include "MutableAttrList.hxx"
33
#include "PropertyActionsOASIS.hxx"
34
#include "StyleOASISTContext.hxx"
35
#include <xmloff/xmluconv.hxx>
36
37
using namespace ::xmloff::token;
38
using namespace ::com::sun::star::uno;
39
using namespace ::com::sun::star::xml::sax;
40
41
const sal_uInt16 aAttrActionMaps[XML_PROP_TYPE_END] =
42
{
43
    PROP_OASIS_GRAPHIC_ATTR_ACTIONS,
44
    PROP_OASIS_DRAWING_PAGE_ATTR_ACTIONS,               // DRAWING_PAGE
45
    PROP_OASIS_PAGE_LAYOUT_ATTR_ACTIONS,
46
    PROP_OASIS_HEADER_FOOTER_ATTR_ACTIONS,
47
    PROP_OASIS_TEXT_ATTR_ACTIONS,
48
    PROP_OASIS_PARAGRAPH_ATTR_ACTIONS,
49
    MAX_OASIS_PROP_ACTIONS,             // RUBY
50
    PROP_OASIS_SECTION_ATTR_ACTIONS,
51
    PROP_OASIS_TABLE_ATTR_ACTIONS,
52
    PROP_OASIS_TABLE_COLUMN_ATTR_ACTIONS,
53
    PROP_OASIS_TABLE_ROW_ATTR_ACTIONS,
54
    PROP_OASIS_TABLE_CELL_ATTR_ACTIONS,
55
    PROP_OASIS_LIST_LEVEL_ATTR_ACTIONS,
56
    PROP_OASIS_CHART_ATTR_ACTIONS
57
};
58
59
class XMLPropertiesTContext_Impl : public XMLPersElemContentTContext
60
{
61
    rtl::Reference< XMLMutableAttributeList > m_xAttrList;
62
63
    XMLPropType m_ePropType;
64
    bool const  m_bControlStyle;
65
66
public:
67
68
    void SetQNameAndPropType( const OUString& rQName,
69
                                 XMLPropType ePropType  )
70
0
    {
71
0
        m_ePropType = ePropType;
72
0
        XMLTransformerContext::SetQName( rQName );
73
0
    };
74
75
    XMLPropertiesTContext_Impl( XMLTransformerBase& rTransformer,
76
                           const OUString& rQName,
77
                           XMLPropType eP,
78
                           bool _bControlStyle );
79
80
    virtual void StartElement( const css::uno::Reference< css::xml::sax::XAttributeList >& xAttrList ) override;
81
82
    virtual void Export() override;
83
84
    static XMLPropType GetPropType( std::u16string_view rLocalName );
85
86
    static OUString const & MergeUnderline( XMLTokenEnum eUnderline,
87
                                           bool bBold, bool bDouble );
88
    static OUString const & MergeLineThrough( XMLTokenEnum eLineThrough,
89
                                        bool bBold, bool bDouble,
90
                                           sal_Unicode c );
91
};
92
93
XMLPropertiesTContext_Impl::XMLPropertiesTContext_Impl(
94
    XMLTransformerBase& rImp, const OUString& rQName, XMLPropType eP,
95
    bool _bControlStyle ) :
96
0
    XMLPersElemContentTContext( rImp, rQName, XML_NAMESPACE_STYLE,
97
0
                                XML_PROPERTIES),
98
0
    m_ePropType( eP ),
99
0
    m_bControlStyle( _bControlStyle )
100
0
{
101
0
}
102
103
void XMLPropertiesTContext_Impl::StartElement(
104
        const Reference< XAttributeList >& rAttrList )
105
0
{
106
0
    XMLTransformerActions *pActions =  nullptr;
107
0
    sal_uInt16 nActionMap = aAttrActionMaps[m_ePropType];
108
0
    if( nActionMap < MAX_OASIS_PROP_ACTIONS )
109
0
    {
110
0
        pActions = GetTransformer().GetUserDefinedActions( nActionMap );
111
0
        OSL_ENSURE( pActions, "go no actions" );
112
0
    }
113
114
0
    if( pActions )
115
0
    {
116
0
        if( !m_xAttrList.is() )
117
0
            m_xAttrList = new XMLMutableAttributeList();
118
0
        rtl::Reference<XMLMutableAttributeList> pAttrList = m_xAttrList;
119
120
0
        XMLTokenEnum eUnderline = XML_TOKEN_END;
121
0
        bool bBoldUnderline = false, bDoubleUnderline = false;
122
0
        XMLTokenEnum eLineThrough = XML_TOKEN_END;
123
0
        bool bBoldLineThrough = false, bDoubleLineThrough = false;
124
0
        sal_Unicode cLineThroughChar = 0;
125
126
0
        bool bIntervalMinorFound = false;
127
0
        double fIntervalMajor = 0.0;
128
0
        sal_Int32 nIntervalMinorDivisor = 0;
129
130
        // #i25616#
131
0
        OUString aOpacityValueRemember;
132
0
        OUString aImageOpacityValueRemember;
133
134
0
        sal_Int16 nAttrCount = rAttrList.is() ? rAttrList->getLength() : 0;
135
0
        for( sal_Int16 i=0; i < nAttrCount; i++ )
136
0
        {
137
0
            const OUString aAttrName = rAttrList->getNameByIndex( i );
138
0
            const OUString aAttrValue = rAttrList->getValueByIndex( i );
139
0
            OUString aLocalName;
140
0
            sal_uInt16 nPrefix =
141
0
                GetTransformer().GetNamespaceMap().GetKeyByAttrName( aAttrName,
142
0
                                                                 &aLocalName );
143
144
0
            XMLTransformerActions::key_type aKey( nPrefix, aLocalName );
145
0
            XMLTransformerActions::const_iterator aIter =
146
0
                pActions->find( aKey );
147
0
            if( aIter != pActions->end() )
148
0
            {
149
0
                switch( (*aIter).second.m_nActionType )
150
0
                {
151
0
                case XML_ATACTION_REMOVE:
152
0
                    break;
153
0
                case XML_ATACTION_COPY:
154
0
                    pAttrList->AddAttribute( aAttrName, aAttrValue );
155
0
                    break;
156
0
                case XML_ATACTION_RENAME:
157
0
                    {
158
0
                        OUString aNewAttrQName(
159
0
                            GetTransformer().GetNamespaceMap().GetQNameByKey(
160
0
                                (*aIter).second.GetQNamePrefixFromParam1(),
161
0
                                ::xmloff::token::GetXMLToken(
162
0
                                (*aIter).second.GetQNameTokenFromParam1()) ) );
163
0
                        pAttrList->AddAttribute( aNewAttrQName, aAttrValue );
164
0
                    }
165
0
                    break;
166
0
                case XML_ATACTION_IN2INCH:
167
0
                    {
168
0
                        OUString aAttrValue2( aAttrValue );
169
0
                        XMLTransformerBase::ReplaceSingleInWithInch(
170
0
                                aAttrValue2 );
171
0
                        pAttrList->AddAttribute( aAttrName, aAttrValue2 );
172
0
                    }
173
0
                    break;
174
0
                case XML_ATACTION_INS2INCHS:
175
0
                    {
176
0
                        OUString aAttrValue2( aAttrValue );
177
0
                        XMLTransformerBase::ReplaceInWithInch(
178
0
                                aAttrValue2 );
179
0
                        pAttrList->AddAttribute( aAttrName, aAttrValue2 );
180
0
                    }
181
0
                    break;
182
0
                case XML_ATACTION_DECODE_STYLE_NAME_REF:
183
0
                    {
184
0
                        OUString aAttrValue2( aAttrValue );
185
0
                        XMLTransformerBase::DecodeStyleName(aAttrValue2);
186
0
                        pAttrList->AddAttribute( aAttrName, aAttrValue2 );
187
0
                    }
188
0
                    break;
189
0
                case XML_ATACTION_RENAME_DECODE_STYLE_NAME_REF:
190
0
                    {
191
0
                        OUString aNewAttrQName(
192
0
                            GetTransformer().GetNamespaceMap().GetQNameByKey(
193
0
                                (*aIter).second.GetQNamePrefixFromParam1(),
194
0
                                ::xmloff::token::GetXMLToken(
195
0
                                (*aIter).second.GetQNameTokenFromParam1()) ) );
196
0
                        OUString aAttrValue2( aAttrValue );
197
0
                        XMLTransformerBase::DecodeStyleName(aAttrValue2);
198
0
                        pAttrList->AddAttribute( aNewAttrQName, aAttrValue2 );
199
0
                    }
200
0
                    break;
201
0
                case XML_ATACTION_NEG_PERCENT:
202
0
                    {
203
0
                        OUString aAttrValue2( aAttrValue );
204
0
                        XMLTransformerBase::NegPercent(aAttrValue2);
205
0
                        pAttrList->AddAttribute( aAttrName, aAttrValue2 );
206
0
                    }
207
0
                    break;
208
0
                case XML_ATACTION_RENAME_NEG_PERCENT:
209
0
                    {
210
0
                        OUString aNewAttrQName(
211
0
                            GetTransformer().GetNamespaceMap().GetQNameByKey(
212
0
                                (*aIter).second.GetQNamePrefixFromParam1(),
213
0
                                ::xmloff::token::GetXMLToken(
214
0
                                (*aIter).second.GetQNameTokenFromParam1()) ) );
215
0
                        OUString aAttrValue2( aAttrValue );
216
0
                        XMLTransformerBase::NegPercent(aAttrValue2);
217
0
                        pAttrList->AddAttribute( aNewAttrQName, aAttrValue2 );
218
0
                    }
219
0
                    break;
220
0
                case XML_OPTACTION_LINE_MODE:
221
0
                    {
222
0
                        bool bWordMode =
223
0
                            IsXMLToken( aAttrValue, XML_SKIP_WHITE_SPACE );
224
0
                        OUString aAttrQName(
225
0
                            GetTransformer().GetNamespaceMap().GetQNameByKey(
226
0
                                XML_NAMESPACE_FO,
227
0
                                GetXMLToken( XML_SCORE_SPACES ) ) );
228
0
                        sal_Int16 nIndex =
229
0
                            pAttrList->GetIndexByName( aAttrQName );
230
0
                        if( -1 != nIndex )
231
0
                        {
232
0
                            if( bWordMode )
233
0
                            {
234
0
                                const OUString aOldValue =
235
0
                                    pAttrList->getValueByIndex( nIndex );
236
0
                                if( !IsXMLToken( aOldValue, XML_TRUE ) )
237
0
                                {
238
0
                                    pAttrList->SetValueByIndex( nIndex,
239
0
                                            GetXMLToken( XML_TRUE ) );
240
0
                                }
241
0
                            }
242
0
                        }
243
0
                        else
244
0
                        {
245
0
                            const OUString& aAttrValue2( GetXMLToken( bWordMode
246
0
                                        ? XML_FALSE
247
0
                                        : XML_TRUE ) );
248
0
                            pAttrList->AddAttribute( aAttrQName, aAttrValue2 );
249
0
                        }
250
0
                    }
251
0
                    break;
252
0
                case XML_OPTACTION_KEEP_WITH_NEXT:
253
0
                    {
254
0
                        const OUString& aAttrValue2( GetXMLToken(
255
0
                                        IsXMLToken( aAttrValue, XML_ALWAYS )
256
0
                                                    ? XML_TRUE
257
0
                                                    : XML_FALSE) );
258
0
                        pAttrList->AddAttribute( aAttrName, aAttrValue2 );
259
0
                    }
260
0
                    break;
261
0
                case XML_OPTACTION_UNDERLINE_WIDTH:
262
0
                    if( IsXMLToken( aAttrValue, XML_BOLD ) )
263
0
                        bBoldUnderline = true;
264
0
                    break;
265
0
                case XML_OPTACTION_UNDERLINE_TYPE:
266
0
                    if( IsXMLToken( aAttrValue, XML_DOUBLE ) )
267
0
                        bDoubleUnderline = true;
268
0
                    break;
269
0
                case XML_OPTACTION_UNDERLINE_STYLE:
270
0
                    eUnderline = GetTransformer().GetToken( aAttrValue );
271
0
                    break;
272
0
                case XML_OPTACTION_LINETHROUGH_WIDTH:
273
0
                    if( IsXMLToken( aAttrValue, XML_BOLD ) )
274
0
                        bBoldLineThrough = true;
275
0
                    break;
276
0
                case XML_OPTACTION_LINETHROUGH_TYPE:
277
0
                    if( IsXMLToken( aAttrValue, XML_DOUBLE ) )
278
0
                        bDoubleLineThrough = true;
279
0
                    break;
280
0
                case XML_OPTACTION_LINETHROUGH_STYLE:
281
0
                    eLineThrough = GetTransformer().GetToken( aAttrValue );
282
0
                    break;
283
0
                case XML_OPTACTION_LINETHROUGH_TEXT:
284
0
                    if( !aAttrValue.isEmpty() )
285
0
                        cLineThroughChar = aAttrValue[0];
286
0
                    break;
287
0
                case XML_OPTACTION_INTERPOLATION:
288
0
                    {
289
                        // 0: none (default)
290
0
                        sal_Int32 nSplineType = 0;
291
0
                        if( IsXMLToken( aAttrValue, XML_CUBIC_SPLINE ))
292
0
                            nSplineType = 1;
293
0
                        else if( IsXMLToken( aAttrValue, XML_B_SPLINE ))
294
0
                            nSplineType = 2;
295
296
0
                        pAttrList->AddAttribute(
297
0
                            GetTransformer().GetNamespaceMap().GetQNameByKey(
298
0
                                XML_NAMESPACE_CHART,
299
0
                                GetXMLToken( XML_SPLINES )),
300
0
                            OUString::number( nSplineType ));
301
0
                    }
302
0
                    break;
303
0
                case XML_OPTACTION_INTERVAL_MAJOR:
304
0
                    pAttrList->AddAttribute( aAttrName, aAttrValue );
305
0
                    ::sax::Converter::convertDouble(fIntervalMajor, aAttrValue);
306
0
                    break;
307
0
                case XML_OPTACTION_INTERVAL_MINOR_DIVISOR:
308
0
                    ::sax::Converter::convertNumber(nIntervalMinorDivisor, aAttrValue);
309
0
                    bIntervalMinorFound = true;
310
0
                    break;
311
0
                case XML_OPTACTION_SYMBOL_TYPE:
312
0
                    {
313
                        // if symbol_type is "named-symbol" the "symbol"
314
                        // property is set in the action XML_OPTACTION_SYMBOL_NAME
315
0
                        sal_Int32 nSymbolType = 0;
316
0
                        if( IsXMLToken( aAttrValue, XML_NONE ))
317
0
                            nSymbolType = -3;
318
0
                        else if( IsXMLToken( aAttrValue, XML_AUTOMATIC ))
319
0
                            nSymbolType = -2;
320
0
                        else if( IsXMLToken( aAttrValue, XML_IMAGE ))
321
0
                            nSymbolType = -1;
322
323
0
                        if( nSymbolType < 0 )
324
0
                            pAttrList->AddAttribute(
325
0
                                GetTransformer().GetNamespaceMap().GetQNameByKey(
326
0
                                    XML_NAMESPACE_CHART,
327
0
                                    GetXMLToken( XML_SYMBOL )),
328
0
                                OUString::number( nSymbolType ));
329
0
                    }
330
0
                    break;
331
0
                case XML_OPTACTION_SYMBOL_NAME:
332
0
                    {
333
                        // assume "symbol-type" == "named-symbol"
334
0
                        sal_Int32 nSymbolType = -3; // NONE
335
                        // "square" just has an awkward token-name
336
0
                        if( IsXMLToken( aAttrValue, XML_GRADIENTSTYLE_SQUARE ))
337
0
                            nSymbolType = 0;
338
0
                        else if( IsXMLToken( aAttrValue, XML_DIAMOND ))
339
0
                            nSymbolType = 1;
340
0
                        else if( IsXMLToken( aAttrValue, XML_ARROW_DOWN ))
341
0
                            nSymbolType = 2;
342
0
                        else if( IsXMLToken( aAttrValue, XML_ARROW_UP ))
343
0
                            nSymbolType = 3;
344
0
                        else if( IsXMLToken( aAttrValue, XML_ARROW_RIGHT ))
345
0
                            nSymbolType = 4;
346
0
                        else if( IsXMLToken( aAttrValue, XML_ARROW_LEFT ))
347
0
                            nSymbolType = 5;
348
0
                        else if( IsXMLToken( aAttrValue, XML_BOW_TIE ))
349
0
                            nSymbolType = 6;
350
0
                        else if( IsXMLToken( aAttrValue, XML_HOURGLASS ))
351
0
                            nSymbolType = 7;
352
0
                        else if( IsXMLToken( aAttrValue, XML_CIRCLE ))
353
0
                            nSymbolType = 8;
354
0
                        else if( IsXMLToken( aAttrValue, XML_STAR ))
355
0
                            nSymbolType = 9;
356
0
                        else if( IsXMLToken( aAttrValue, XML_X ))
357
0
                            nSymbolType = 10;
358
0
                        else if( IsXMLToken( aAttrValue, XML_PLUS ))
359
0
                            nSymbolType = 11;
360
0
                        else if( IsXMLToken( aAttrValue, XML_ASTERISK ))
361
0
                            nSymbolType = 12;
362
0
                        else if( IsXMLToken( aAttrValue, XML_HORIZONTAL_BAR ))
363
0
                            nSymbolType = 13;
364
0
                        else if( IsXMLToken( aAttrValue, XML_VERTICAL_BAR ))
365
0
                            nSymbolType = 14;
366
367
0
                        if( nSymbolType >= 0 )
368
0
                            pAttrList->AddAttribute(
369
0
                                GetTransformer().GetNamespaceMap().GetQNameByKey(
370
0
                                    XML_NAMESPACE_CHART,
371
0
                                    GetXMLToken( XML_SYMBOL )),
372
0
                                OUString::number( nSymbolType ));
373
0
                    }
374
0
                    break;
375
                // #i25616#
376
0
                case XML_OPTACTION_OPACITY:
377
0
                    aOpacityValueRemember = aAttrValue;
378
0
                    XMLTransformerBase::NegPercent(aOpacityValueRemember);
379
0
                    break;
380
381
                // #i25616#
382
0
                case XML_OPTACTION_IMAGE_OPACITY:
383
0
                    aImageOpacityValueRemember = aAttrValue;
384
0
                    XMLTransformerBase::NegPercent(aImageOpacityValueRemember);
385
0
                    break;
386
387
0
                case XML_OPTACTION_KEEP_TOGETHER:
388
0
                    pAttrList->AddAttribute(
389
0
                        GetTransformer().GetNamespaceMap().GetQNameByKey(
390
0
                            XML_NAMESPACE_STYLE,GetXMLToken(XML_BREAK_INSIDE)),
391
0
                        GetXMLToken(
392
0
                            IsXMLToken( aAttrValue, XML_ALWAYS )
393
0
                            ? XML_COLUMNSPLIT_AVOID
394
0
                            : XML_AUTO ) );
395
0
                    break;
396
397
0
                case XML_OPTACTION_CONTROL_TEXT_ALIGN:
398
0
                    if ( m_bControlStyle )
399
0
                    {
400
0
                        OUString aNewAttrQName(
401
0
                            GetTransformer().GetNamespaceMap().GetQNameByKey(
402
0
                                XML_NAMESPACE_STYLE,
403
0
                                ::xmloff::token::GetXMLToken(
404
0
                                XML_TEXT_ALIGN ) ) );
405
0
                        pAttrList->AddAttribute( aNewAttrQName, aAttrValue );
406
0
                    }
407
0
                    else
408
0
                    {
409
0
                        OUString aNewAttrQName(
410
0
                            GetTransformer().GetNamespaceMap().GetQNameByKey(
411
0
                                XML_NAMESPACE_FO,
412
0
                                ::xmloff::token::GetXMLToken(
413
0
                                XML_TEXT_ALIGN ) ) );
414
0
                        pAttrList->AddAttribute( aNewAttrQName, aAttrValue );
415
0
                    }
416
0
                    break;
417
418
0
                case XML_ATACTION_CAPTION_ESCAPE_OASIS:
419
0
                    {
420
0
                        OUString aAttrValue2( aAttrValue );
421
0
                        if( aAttrValue2.indexOf( '%' ) != -1 )
422
0
                        {
423
0
                            sal_Int32 nValue = 0;
424
0
                            ::sax::Converter::convertPercent(nValue, aAttrValue);
425
0
                            if( nValue )
426
0
                            {
427
0
                                nValue *= 100;
428
0
                                OUStringBuffer aOut;
429
0
                                ::sax::Converter::convertPercent(aOut, nValue);
430
0
                                aAttrValue2 = aOut.makeStringAndClear();
431
0
                            }
432
0
                        }
433
0
                        else
434
0
                        {
435
0
                            XMLTransformerBase::ReplaceSingleInWithInch( aAttrValue2 );
436
0
                        }
437
438
0
                        pAttrList->AddAttribute( aAttrName, aAttrValue2 );
439
0
                    }
440
0
                    break;
441
442
0
                case XML_ATACTION_DECODE_PROTECT:
443
0
                    {
444
0
                        pAttrList->AddAttribute( aAttrName, aAttrValue );
445
446
0
                        if( aAttrValue.indexOf( GetXMLToken( XML_SIZE ) ) != -1 )
447
0
                            pAttrList->AddAttribute( GetTransformer().GetNamespaceMap().GetQNameByKey(
448
0
                                    XML_NAMESPACE_DRAW,
449
0
                                    GetXMLToken( XML_SIZE_PROTECT )), GetXMLToken( XML_TRUE ) );
450
451
0
                        if( aAttrValue.indexOf( GetXMLToken( XML_POSITION ) ) != -1 )
452
0
                            pAttrList->AddAttribute( GetTransformer().GetNamespaceMap().GetQNameByKey(
453
0
                                    XML_NAMESPACE_DRAW,
454
0
                                    GetXMLToken( XML_MOVE_PROTECT )), GetXMLToken( XML_TRUE ) );
455
0
                    }
456
0
                    break;
457
458
0
                case XML_ATACTION_DRAW_MIRROR_OASIS: // renames style:mirror to draw:mirror and adapts values
459
0
                    {
460
                        // keep original for writer graphic objects
461
                        // Adapts attribute values (#i49139#)
462
0
                        OUStringBuffer aNewAttrValue;
463
0
                        SvXMLTokenEnumerator aTokenEnum( aAttrValue );
464
0
                        std::u16string_view aToken;
465
0
                        while( aTokenEnum.getNextToken( aToken ) )
466
0
                        {
467
0
                            if ( !aNewAttrValue.isEmpty() )
468
0
                            {
469
0
                                aNewAttrValue.append(" ");
470
0
                            }
471
472
0
                            if ( IsXMLToken( aToken, XML_HORIZONTAL_ON_EVEN ) )
473
0
                            {
474
0
                                aNewAttrValue.append(GetXMLToken( XML_HORIZONTAL_ON_LEFT_PAGES ));
475
0
                            }
476
0
                            else if ( IsXMLToken( aToken, XML_HORIZONTAL_ON_ODD ) )
477
0
                            {
478
0
                                aNewAttrValue.append(GetXMLToken( XML_HORIZONTAL_ON_RIGHT_PAGES ));
479
0
                            }
480
0
                            else
481
0
                            {
482
0
                                aNewAttrValue.append(aToken);
483
0
                            }
484
0
                        }
485
0
                        pAttrList->AddAttribute( aAttrName, aNewAttrValue.makeStringAndClear() );
486
487
                        // create old draw:mirror for drawing graphic objects
488
0
                        const OUString& aAttrValue2( GetXMLToken( IsXMLToken( aAttrValue, XML_HORIZONTAL ) ? XML_TRUE : XML_FALSE ) );
489
0
                        pAttrList->AddAttribute( GetTransformer().GetNamespaceMap().GetQNameByKey(
490
0
                                    XML_NAMESPACE_DRAW,
491
0
                                    GetXMLToken( XML_MIRROR )), aAttrValue2 );
492
0
                    }
493
0
                    break;
494
0
                case XML_ATACTION_GAMMA_OASIS:       // converts percentage value to double
495
0
                    {
496
0
                        sal_Int32 nValue;
497
0
                        ::sax::Converter::convertPercent( nValue, aAttrValue );
498
0
                        const double fValue = static_cast<double>(nValue) / 100.0;
499
0
                        pAttrList->AddAttribute( aAttrName, OUString::number( fValue ) );
500
0
                    }
501
0
                    break;
502
0
                case XML_ATACTION_OPACITY_FIX:
503
0
                    {
504
0
                        sal_Int32 nValue;
505
0
                        if( aAttrValue.indexOf( '%' ) != -1 )
506
0
                        {
507
0
                            ::sax::Converter::convertPercent(nValue, aAttrValue);
508
0
                        }
509
0
                        else
510
0
                        {
511
0
                            nValue = sal_Int32( aAttrValue.toDouble() * 100.0 );
512
0
                        }
513
0
                        nValue = 100 - nValue;
514
515
0
                        OUStringBuffer aOut;
516
0
                        ::sax::Converter::convertPercent(aOut, nValue);
517
0
                        pAttrList->AddAttribute( aAttrName, aOut.makeStringAndClear() );
518
0
                    }
519
0
                    break;
520
0
                default:
521
0
                    OSL_ENSURE( false, "unknown action" );
522
0
                    break;
523
0
                }
524
0
            }
525
0
            else
526
0
            {
527
0
                pAttrList->AddAttribute( aAttrName, aAttrValue );
528
0
            }
529
0
        }
530
0
        if( XML_TOKEN_END != eUnderline )
531
0
            pAttrList->AddAttribute(
532
0
                    GetTransformer().GetNamespaceMap().GetQNameByKey(
533
0
                        XML_NAMESPACE_STYLE,
534
0
                        GetXMLToken( XML_TEXT_UNDERLINE ) ),
535
0
                    MergeUnderline( eUnderline, bBoldUnderline,
536
0
                                    bDoubleUnderline ) );
537
0
        if( XML_TOKEN_END != eLineThrough )
538
0
            pAttrList->AddAttribute(
539
0
                    GetTransformer().GetNamespaceMap().GetQNameByKey(
540
0
                        XML_NAMESPACE_STYLE,
541
0
                        GetXMLToken( XML_TEXT_CROSSING_OUT ) ),
542
0
                    MergeLineThrough( eLineThrough, bBoldLineThrough,
543
0
                                    bDoubleLineThrough, cLineThroughChar ) );
544
0
        if( bIntervalMinorFound )
545
0
        {
546
0
            double fIntervalMinor = 0.0;
547
0
            if( nIntervalMinorDivisor != 0)
548
0
                fIntervalMinor = fIntervalMajor / static_cast< double >( nIntervalMinorDivisor );
549
550
0
            OUStringBuffer aBuf;
551
0
            ::sax::Converter::convertDouble( aBuf, fIntervalMinor );
552
0
            pAttrList->AddAttribute(
553
0
                GetTransformer().GetNamespaceMap().GetQNameByKey(
554
0
                    XML_NAMESPACE_CHART,
555
0
                    GetXMLToken( XML_INTERVAL_MINOR )),
556
0
                aBuf.makeStringAndClear());
557
0
        }
558
559
        // #i25616#
560
0
        if(!aOpacityValueRemember.isEmpty() || !aImageOpacityValueRemember.isEmpty())
561
0
        {
562
0
            pAttrList->AddAttribute(
563
0
                    GetTransformer().GetNamespaceMap().GetQNameByKey(
564
0
                        XML_NAMESPACE_DRAW,
565
0
                        GetXMLToken( XML_TRANSPARENCY ) ),
566
0
                    !aImageOpacityValueRemember.isEmpty()
567
0
                    ? aImageOpacityValueRemember : aOpacityValueRemember );
568
0
        }
569
0
    }
570
0
    else
571
0
    {
572
0
        if( !m_xAttrList.is() )
573
0
        {
574
0
            m_xAttrList = new XMLMutableAttributeList( rAttrList, true );
575
0
        }
576
0
        else
577
0
        {
578
0
            m_xAttrList->AppendAttributeList( rAttrList );
579
0
        }
580
0
    }
581
0
}
582
583
void XMLPropertiesTContext_Impl::Export()
584
0
{
585
0
    GetTransformer().GetDocHandler()->startElement( GetExportQName(), m_xAttrList );
586
0
    ExportContent();
587
0
    GetTransformer().GetDocHandler()->endElement( GetExportQName() );
588
0
}
589
590
XMLPropType XMLPropertiesTContext_Impl::GetPropType( std::u16string_view rLocalName )
591
0
{
592
0
    XMLPropType eProp = XML_PROP_TYPE_END;
593
0
    if( IsXMLToken( rLocalName, XML_GRAPHIC_PROPERTIES )  )
594
0
        eProp = XML_PROP_TYPE_GRAPHIC;
595
0
    else if( IsXMLToken( rLocalName, XML_DRAWING_PAGE_PROPERTIES ) )
596
0
        eProp = XML_PROP_TYPE_DRAWING_PAGE;
597
0
    else if( IsXMLToken( rLocalName, XML_PAGE_LAYOUT_PROPERTIES ) )
598
0
        eProp = XML_PROP_TYPE_PAGE_LAYOUT;
599
0
    else if( IsXMLToken( rLocalName, XML_HEADER_FOOTER_PROPERTIES ) )
600
0
        eProp = XML_PROP_TYPE_HEADER_FOOTER;
601
0
    else if( IsXMLToken( rLocalName, XML_TEXT_PROPERTIES ) )
602
0
        eProp = XML_PROP_TYPE_TEXT;
603
0
    else if( IsXMLToken( rLocalName, XML_PARAGRAPH_PROPERTIES ) )
604
0
        eProp = XML_PROP_TYPE_PARAGRAPH;
605
0
    else if( IsXMLToken( rLocalName, XML_RUBY_PROPERTIES ) )
606
0
        eProp = XML_PROP_TYPE_RUBY;
607
0
    else if( IsXMLToken( rLocalName, XML_SECTION_PROPERTIES ) )
608
0
        eProp = XML_PROP_TYPE_SECTION;
609
0
    else if( IsXMLToken( rLocalName, XML_TABLE_PROPERTIES ) )
610
0
        eProp = XML_PROP_TYPE_TABLE;
611
0
    else if( IsXMLToken( rLocalName, XML_TABLE_COLUMN_PROPERTIES ) )
612
0
        eProp = XML_PROP_TYPE_TABLE_COLUMN;
613
0
    else if( IsXMLToken( rLocalName, XML_TABLE_ROW_PROPERTIES ) )
614
0
        eProp = XML_PROP_TYPE_TABLE_ROW;
615
0
    else if( IsXMLToken( rLocalName, XML_TABLE_CELL_PROPERTIES ) )
616
0
        eProp = XML_PROP_TYPE_TABLE_CELL;
617
0
    else if( IsXMLToken( rLocalName, XML_LIST_LEVEL_PROPERTIES ) )
618
0
        eProp = XML_PROP_TYPE_LIST_LEVEL;
619
0
    else if( IsXMLToken( rLocalName, XML_CHART_PROPERTIES ) )
620
0
        eProp = XML_PROP_TYPE_CHART;
621
622
0
    return eProp;
623
0
}
624
625
OUString const & XMLPropertiesTContext_Impl::MergeUnderline(
626
            XMLTokenEnum eUnderline, bool bBold, bool bDouble )
627
0
{
628
0
    if( bDouble )
629
0
    {
630
0
        switch( eUnderline )
631
0
        {
632
0
        case XML_WAVE:
633
0
            eUnderline = XML_DOUBLE_WAVE;
634
0
            break;
635
0
        default:
636
0
            eUnderline = XML_DOUBLE;
637
0
            break;
638
0
        }
639
0
    }
640
0
    else if( bBold )
641
0
    {
642
0
        switch( eUnderline )
643
0
        {
644
0
        case XML_NONE:
645
0
        case XML_SOLID:
646
0
            eUnderline = XML_BOLD;
647
0
            break;
648
0
        case XML_DOTTED:
649
0
            eUnderline = XML_BOLD_DOTTED;
650
0
            break;
651
0
        case XML_DASH:
652
0
            eUnderline = XML_BOLD_DASH;
653
0
            break;
654
0
        case XML_LONG_DASH:
655
0
            eUnderline = XML_BOLD_LONG_DASH;
656
0
            break;
657
0
        case XML_DOT_DASH:
658
0
            eUnderline = XML_BOLD_DOT_DASH;
659
0
            break;
660
0
        case XML_DOT_DOT_DASH:
661
0
            eUnderline = XML_BOLD_DOT_DOT_DASH;
662
0
            break;
663
0
        case XML_WAVE:
664
0
            eUnderline = XML_BOLD_WAVE;
665
0
            break;
666
0
        default:
667
0
            OSL_FAIL( "xmloff::XMLPropertiesTContext_Impl::MergeUnderline(), missing underline case!" );
668
0
            break;
669
0
        }
670
0
    }
671
0
    else
672
0
    {
673
0
        switch( eUnderline )
674
0
        {
675
0
        case XML_SOLID:
676
0
            eUnderline = XML_SINGLE;
677
0
            break;
678
0
        case XML_NONE:
679
0
            eUnderline = XML_NONE;
680
0
            break;
681
0
        default:
682
0
            OSL_FAIL( "xmloff::XMLPropertiesTContext_Impl::MergeUnderline(), missing underline case!" );
683
0
            break;
684
0
        }
685
0
    }
686
687
0
    return GetXMLToken( eUnderline );
688
0
}
689
690
OUString const & XMLPropertiesTContext_Impl::MergeLineThrough(
691
            XMLTokenEnum eLineThrough, bool bBold, bool bDouble,
692
               sal_Unicode c )
693
0
{
694
0
    if( c )
695
0
        eLineThrough = c=='/' ? XML_SLASH : XML_uX;
696
0
    else if( bDouble )
697
0
        eLineThrough = XML_DOUBLE_LINE;
698
0
    else if( bBold )
699
0
        eLineThrough = XML_THICK_LINE;
700
0
    else if( XML_NONE != eLineThrough )
701
0
        eLineThrough = XML_SINGLE_LINE;
702
703
0
    return GetXMLToken( eLineThrough );
704
0
}
705
706
XMLStyleOASISTContext::XMLStyleOASISTContext(XMLTransformerBase& rImp,
707
    const OUString& rQName, bool bPersistent)
708
0
    : XMLPersElemContentTContext(rImp, rQName)
709
0
    , m_bPersistent(bPersistent)
710
0
    , m_bControlStyle(false)
711
0
{
712
0
}
713
714
XMLStyleOASISTContext::XMLStyleOASISTContext(
715
    XMLTransformerBase& rImp, const OUString& rQName,
716
    sal_uInt16 nPrefix, ::xmloff::token::XMLTokenEnum eToken,
717
    bool bPersistent)
718
0
    : XMLPersElemContentTContext(rImp, rQName, nPrefix, eToken)
719
0
    , m_bPersistent(bPersistent)
720
0
    , m_bControlStyle(false)
721
0
{
722
0
}
723
724
XMLStyleOASISTContext::~XMLStyleOASISTContext()
725
0
{
726
0
}
727
728
rtl::Reference<XMLTransformerContext> XMLStyleOASISTContext::CreateChildContext(
729
            sal_uInt16 nPrefix,
730
            const OUString& rLocalName,
731
            const OUString& rQName,
732
            const Reference< XAttributeList >& rAttrList )
733
0
{
734
0
    rtl::Reference<XMLTransformerContext> pContext;
735
736
0
    if( XML_NAMESPACE_STYLE == nPrefix || XML_NAMESPACE_LO_EXT == nPrefix )
737
0
    {
738
0
        XMLPropType ePropType =
739
0
            XMLPropertiesTContext_Impl::GetPropType( rLocalName );
740
0
        if( XML_PROP_TYPE_END != ePropType )
741
0
        {
742
            // if no properties context exist start a new one.
743
0
            if( !m_xPropContext.is() )
744
0
                m_xPropContext = new XMLPropertiesTContext_Impl(
745
0
                    GetTransformer(), rQName, ePropType, m_bControlStyle );
746
0
            else
747
0
                m_xPropContext->SetQNameAndPropType( rQName, ePropType );
748
0
            pContext = m_xPropContext;
749
0
        }
750
0
    }
751
0
    if( !pContext.is() )
752
0
    {
753
        // if a properties context exist close it
754
0
        if( m_xPropContext.is() && !m_bPersistent )
755
0
        {
756
0
            m_xPropContext->Export();
757
0
            m_xPropContext = nullptr;
758
0
        }
759
760
0
        pContext = m_bPersistent
761
0
                        ? XMLPersElemContentTContext::CreateChildContext(
762
0
                                nPrefix, rLocalName, rQName, rAttrList )
763
0
                        : XMLTransformerContext::CreateChildContext(
764
0
                                nPrefix, rLocalName, rQName, rAttrList );
765
0
    }
766
767
0
    return pContext;
768
0
}
769
770
void XMLStyleOASISTContext::StartElement(
771
        const Reference< XAttributeList >& rAttrList )
772
0
{
773
0
    XMLTransformerActions *pActions =
774
0
        GetTransformer().GetUserDefinedActions( OASIS_STYLE_ACTIONS );
775
0
    OSL_ENSURE( pActions, "go no actions" );
776
777
0
    Reference< XAttributeList > xAttrList( rAttrList );
778
0
    rtl::Reference<XMLMutableAttributeList> pMutableAttrList;
779
0
    sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0;
780
0
    sal_Int16 nFamilyAttr = -1;
781
0
    m_bControlStyle = false;
782
783
0
    for( sal_Int16 i=0; i < nAttrCount; i++ )
784
0
    {
785
0
        const OUString aAttrName = xAttrList->getNameByIndex( i );
786
0
        OUString aLocalName;
787
0
        sal_uInt16 nPrefix =
788
0
            GetTransformer().GetNamespaceMap().GetKeyByAttrName( aAttrName,
789
0
                                                                 &aLocalName );
790
0
        XMLTransformerActions::key_type aKey( nPrefix, aLocalName );
791
0
        XMLTransformerActions::const_iterator aIter =
792
0
            pActions->find( aKey );
793
0
        if( aIter != pActions->end() )
794
0
        {
795
0
            if( !pMutableAttrList )
796
0
            {
797
0
                pMutableAttrList =
798
0
                        new XMLMutableAttributeList( xAttrList );
799
0
                xAttrList = pMutableAttrList;
800
0
            }
801
0
            const OUString aAttrValue = xAttrList->getValueByIndex( i );
802
0
            switch( (*aIter).second.m_nActionType )
803
0
            {
804
0
            case XML_ATACTION_STYLE_FAMILY:
805
0
                if( IsXMLToken( aAttrValue, XML_GRAPHIC ) )
806
0
                {
807
0
                    pMutableAttrList->SetValueByIndex(
808
0
                        i, GetXMLToken(XML_GRAPHICS) );
809
0
                }
810
0
                else
811
0
                {
812
0
                    if( IsXMLToken( aAttrValue, XML_PARAGRAPH ) )
813
0
                        nFamilyAttr = i;
814
0
                }
815
816
0
                break;
817
0
            case XML_ATACTION_STYLE_DISPLAY_NAME:
818
0
            case XML_ATACTION_REMOVE:
819
0
                pMutableAttrList->RemoveAttributeByIndex( i );
820
0
                --i;
821
0
                --nAttrCount;
822
0
                break;
823
0
            case XML_ATACTION_DECODE_STYLE_NAME:
824
0
                m_bControlStyle = aAttrValue.startsWith( "ctrl" );
825
0
                [[fallthrough]];
826
0
            case XML_ATACTION_DECODE_STYLE_NAME_REF:
827
0
                {
828
0
                    OUString aAttrValue2( aAttrValue );
829
0
                    if( XMLTransformerBase::DecodeStyleName(aAttrValue2) )
830
0
                        pMutableAttrList->SetValueByIndex( i, aAttrValue2 );
831
0
                }
832
0
                break;
833
0
            case XML_ATACTION_IN2INCH:
834
0
                {
835
0
                    OUString aAttrValue2( aAttrValue );
836
0
                    if( XMLTransformerBase::ReplaceSingleInWithInch(
837
0
                                aAttrValue2 ) )
838
0
                        pMutableAttrList->SetValueByIndex( i, aAttrValue2 );
839
0
                }
840
0
                break;
841
0
            case XML_ATACTION_NEG_PERCENT:
842
0
                {
843
0
                    OUString aAttrValue2( aAttrValue );
844
0
                    if( XMLTransformerBase::NegPercent(aAttrValue2) )
845
0
                        pMutableAttrList->SetValueByIndex( i, aAttrValue2 );
846
0
                }
847
0
                break;
848
0
            case XML_ATACTION_URI_OASIS:
849
0
                {
850
0
                    OUString aAttrValue2( aAttrValue );
851
0
                    if( GetTransformer().ConvertURIToOOo( aAttrValue2,
852
0
                            static_cast< bool >((*aIter).second.m_nParam1)))
853
0
                        pMutableAttrList->SetValueByIndex( i, aAttrValue2 );
854
0
                }
855
0
                break;
856
0
            default:
857
0
                OSL_ENSURE( false, "unknown action" );
858
0
                break;
859
0
            }
860
0
        }
861
0
    }
862
863
0
    if( m_bControlStyle && nFamilyAttr != -1 )
864
0
        pMutableAttrList->SetValueByIndex( nFamilyAttr, GetXMLToken( XML_CONTROL ) );
865
866
0
    if( m_bPersistent )
867
0
        XMLPersElemContentTContext::StartElement( xAttrList );
868
0
    else
869
0
        GetTransformer().GetDocHandler()->startElement( GetExportQName(), xAttrList );
870
0
}
871
872
void XMLStyleOASISTContext::EndElement()
873
0
{
874
0
    if( m_bPersistent )
875
0
    {
876
0
        XMLPersElemContentTContext::EndElement();
877
0
    }
878
0
    else
879
0
    {
880
        // if a properties context exist close it
881
0
        if( m_xPropContext.is() )
882
0
        {
883
0
            m_xPropContext->Export();
884
0
            m_xPropContext = nullptr;
885
0
        }
886
0
        GetTransformer().GetDocHandler()->endElement( GetExportQName() );
887
0
    }
888
0
}
889
890
void XMLStyleOASISTContext::Characters( const OUString& )
891
0
{
892
    // element content only:
893
0
}
894
895
void XMLStyleOASISTContext::ExportContent()
896
0
{
897
0
    if( m_xPropContext.is() )
898
0
        m_xPropContext->Export();
899
0
    XMLPersElemContentTContext::ExportContent();
900
0
}
901
902
bool XMLStyleOASISTContext::IsPersistent() const
903
0
{
904
0
    return m_bPersistent;
905
0
}
906
907
XMLTransformerActions *XMLStyleOASISTContext::CreateTransformerActions(
908
        sal_uInt16 nType )
909
0
{
910
0
    XMLTransformerActionInit const *pInit = nullptr;
911
912
0
    switch( nType )
913
0
    {
914
0
    case PROP_OASIS_GRAPHIC_ATTR_ACTIONS:
915
0
        pInit = aGraphicPropertyOASISAttrActionTable;
916
0
        break;
917
0
    case PROP_OASIS_DRAWING_PAGE_ATTR_ACTIONS:
918
0
        pInit = aDrawingPagePropertyOASISAttrActionTable;
919
0
        break;
920
0
    case PROP_OASIS_PAGE_LAYOUT_ATTR_ACTIONS:
921
0
        pInit = aPageLayoutPropertyOASISAttrActionTable;
922
0
        break;
923
0
    case PROP_OASIS_HEADER_FOOTER_ATTR_ACTIONS:
924
0
        pInit = aHeaderFooterPropertyOASISAttrActionTable;
925
0
        break;
926
0
    case PROP_OASIS_TEXT_ATTR_ACTIONS:
927
0
        pInit = aTextPropertyOASISAttrActionTable;
928
0
        break;
929
0
    case PROP_OASIS_PARAGRAPH_ATTR_ACTIONS:
930
0
        pInit = aParagraphPropertyOASISAttrActionTable;
931
0
        break;
932
0
    case PROP_OASIS_SECTION_ATTR_ACTIONS:
933
0
        pInit = aSectionPropertyOASISAttrActionTable;
934
0
        break;
935
0
    case PROP_OASIS_TABLE_ATTR_ACTIONS:
936
0
        pInit = aTablePropertyOASISAttrActionTable;
937
0
        break;
938
0
    case PROP_OASIS_TABLE_COLUMN_ATTR_ACTIONS:
939
0
        pInit = aTableColumnPropertyOASISAttrActionTable;
940
0
        break;
941
0
    case PROP_OASIS_TABLE_ROW_ATTR_ACTIONS:
942
0
        pInit = aTableRowPropertyOASISAttrActionTable;
943
0
        break;
944
0
    case PROP_OASIS_TABLE_CELL_ATTR_ACTIONS:
945
0
        pInit = aTableCellPropertyOASISAttrActionTable;
946
0
        break;
947
0
    case PROP_OASIS_LIST_LEVEL_ATTR_ACTIONS:
948
0
        pInit = aListLevelPropertyOASISAttrActionTable;
949
0
        break;
950
0
    case PROP_OASIS_CHART_ATTR_ACTIONS:
951
0
        pInit = aChartPropertyOASISAttrActionTable;
952
0
        break;
953
0
    }
954
955
0
    XMLTransformerActions *pActions = nullptr;
956
0
    if( pInit )
957
0
        pActions = new XMLTransformerActions( pInit );
958
959
0
    return pActions;
960
0
}
961
962
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */