Coverage Report

Created: 2025-07-07 10:01

/src/libreoffice/xmloff/source/forms/propertyexport.hxx
Line
Count
Source (jump to first uncovered line)
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
#pragma once
21
22
#include <sal/config.h>
23
24
#include <set>
25
26
#include "formattributes.hxx"
27
#include <com/sun/star/beans/XPropertySet.hpp>
28
#include <com/sun/star/beans/XPropertyState.hpp>
29
#include <xmloff/xmltoken.hxx>
30
#include <xmloff/xmlexp.hxx>
31
#include "callbacks.hxx"
32
#include "strings.hxx"
33
34
enum class BoolAttrFlags {
35
    DefaultFalse          = 0x00,
36
    DefaultTrue           = 0x01,
37
    DefaultVoid           = 0x02,
38
    InverseSemantics      = 0x04,
39
};
40
namespace o3tl {
41
    template<> struct typed_flags<BoolAttrFlags> : is_typed_flags<BoolAttrFlags, 0x07> {};
42
}
43
44
namespace xmloff
45
{
46
47
    // if sal_True, indicates that the semantic of the property referred by <arg>_pPropertyName</arg>
48
    // is inverse to the semantic of the XML attribute.<br/>
49
    // I.e. if the property value is <TRUE/>, <FALSE/> has to be written and vice versa.
50
    // <p>Be careful with <arg>_bDefault</arg> and <arg>_bInverseSemantics</arg>: if <arg>_bInverseSemantics</arg>
51
    // is <TRUE/>, the current property value is inverted <em>before</em> comparing it to the default.</p>
52
53
    class IFormsExportContext;
54
    //= OPropertyExport
55
    /** provides export related tools for attribute handling
56
57
        <p>(The name is somewhat misleading. It's not only a PropertyExport, but in real an ElementExport.
58
        Anyway.)</p>
59
    */
60
    class OPropertyExport
61
    {
62
    private:
63
        std::set<OUString>      m_aRemainingProps;
64
            // see examinePersistence
65
66
        void exportRelativeTargetLocation(const OUString& _sPropertyName, CCAFlags _nProperty,bool _bAddType);
67
68
    protected:
69
        IFormsExportContext&    m_rContext;
70
71
        const css::uno::Reference< css::beans::XPropertySet >
72
                                m_xProps;
73
        const css::uno::Reference< css::beans::XPropertySetInfo >
74
                                m_xPropertyInfo;
75
        const css::uno::Reference< css::beans::XPropertyState >
76
                                m_xPropertyState;
77
78
        // caching
79
        OUString     m_sValueTrue;
80
        OUString     m_sValueFalse;
81
82
    public:
83
        /** constructs an object capable of handling attributes for export
84
            @param  _rContext
85
                the export context to which's attribute list the property translation should be added
86
            @param  m_xControl
87
                the property set to be exported
88
        */
89
        OPropertyExport(IFormsExportContext& _rContext,
90
            const css::uno::Reference< css::beans::XPropertySet >& _rxProps);
91
92
    protected:
93
        /** examines a property set given for all properties which's value are to made persistent
94
95
            <p>upon return the <method>m_aRemainingProps</method> will be filled with the names of all properties
96
            which need to be stored</p>
97
        */
98
        void examinePersistence();
99
100
        template< typename T > void exportRemainingPropertiesSequence(
101
            css::uno::Any const & value,
102
            token::XMLTokenEnum eValueAttName);
103
104
        void exportRemainingProperties();
105
106
        /** indicates that a property has been handled by a derived class, without using the helper methods of this
107
            class.
108
109
            <p>Calling this method is necessary in case you use the suggested mechanism for the generic export of
110
            properties. This means that you want to use <method>exportRemainingProperties</method>, which exports
111
            all properties which need to ('cause they haven't been exported with one of the other type-specific
112
            methods).</p>
113
114
            <p>In this case you should call exportedProperty for every property you export yourself, so the property
115
            will be flagged as <em>already handled</em></p>
116
        */
117
        void exportedProperty(const OUString& _rPropertyName)
118
0
            { m_aRemainingProps.erase(_rPropertyName); }
119
120
        /** add an attribute which is represented by a string property to the export context
121
122
            @param _nNamespaceKey
123
                the key of the namespace to use for the attribute name. Is used with the namespace map
124
                provided by the export context.
125
            @param _pAttributeName
126
                the name of the attribute to add. Must not contain any namespace
127
            @param _pPropertyName
128
                the name of the property to ask the control for
129
        */
130
        void exportStringPropertyAttribute(
131
            const sal_uInt16 _nNamespaceKey,
132
            const OUString& _pAttributeName,
133
            const OUString& _rPropertyName
134
        );
135
136
        /** add an attribute which is represented by a boolean property to the export context
137
138
            @param _nNamespaceKey
139
                the key of the namespace to use for the attribute name. Is used with the namespace map
140
                provided by the export context.
141
            @param _pAttributeName
142
                the name of the attribute to add. Must not contain any namespace (it's added automatically)
143
            @param _pPropertyName
144
                the name of the property to ask the control for
145
            @param _nBooleanAttributeFlags
146
                specifies the default and the "alignment" (inverse semantics) of the boolean property
147
        */
148
        void exportBooleanPropertyAttribute(
149
            const sal_uInt16 _nNamespaceKey,
150
            const OUString& _pAttributeName,
151
            const OUString& _rPropertyName,
152
            const BoolAttrFlags _nBooleanAttributeFlags);
153
154
        /** add an attribute which is represented by a sal_Int16 property to the export context
155
156
            @param _nNamespaceKey
157
                the key of the namespace to use for the attribute name. Is used with the namespace map
158
                provided by the export context.
159
            @param _pAttributeName
160
                the name of the attribute to add. Must not contain any namespace (it's added automatically)
161
            @param _pPropertyName
162
                the name of the property to ask the control for
163
            @param _nDefault
164
                the default of the attribute. See force parameter.
165
            @param force
166
                if true and the property is not set or does not contain a sal_Int16,
167
                then _nDefault is written out.
168
                if false and the current property value equals _nDefault,
169
                then no attribute is added.
170
        */
171
        void exportInt16PropertyAttribute(
172
            const sal_uInt16 _nNamespaceKey,
173
            const OUString& _pAttributeName,
174
            const OUString& _rPropertyName,
175
            const sal_Int16 _nDefault,
176
            const bool force = false);
177
178
        /** add an attribute which is represented by a sal_Int32 property to the export context
179
180
            @param _nNamespaceKey
181
                the key of the namespace to use for the attribute name. Is used with the namespace map
182
                provided by the export context.
183
            @param _pAttributeName
184
                the name of the attribute to add. Must not contain any namespace (it's added automatically)
185
            @param _pPropertyName
186
                the name of the property to ask the control for
187
            @param _nDefault
188
                the default of the attribute. If the current property value equals this default, no
189
                attribute is added.
190
        */
191
        void exportInt32PropertyAttribute(
192
            const sal_uInt16 _nNamespaceKey,
193
            const OUString& _pAttributeName,
194
            const OUString& _rPropertyName,
195
            const sal_Int32 _nDefault);
196
197
        /** add an attribute which is represented by an enum property to the export context
198
199
            @param _nNamespaceKey
200
                the key of the namespace to use for the attribute name. Is used with the namespace map
201
                provided by the export context.
202
            @param _pAttributeName
203
                the name of the attribute to add. Must not contain any namespace (it's added automatically)
204
            @param _pPropertyName
205
                the name of the property to ask the control for
206
            @param _pValueMap
207
                the map to use when converting the property value to an attribute value
208
            @param _nDefault
209
                the default of the attribute. If the current property value equals this default, no
210
                attribute is added.
211
        */
212
        template<typename EnumT>
213
        void exportEnumPropertyAttribute(
214
            const sal_uInt16 _nNamespaceKey,
215
            const OUString& _pAttributeName,
216
            const OUString& _rPropertyName,
217
            const SvXMLEnumMapEntry<EnumT>* _pValueMap,
218
            const EnumT _nDefault,
219
            const bool _bVoidDefault = false)
220
0
        {
221
0
            exportEnumPropertyAttributeImpl(_nNamespaceKey, _pAttributeName, _rPropertyName,
222
0
                            reinterpret_cast<const SvXMLEnumMapEntry<sal_uInt16>*>(_pValueMap),
223
0
                            static_cast<sal_Int16>(_nDefault), _bVoidDefault);
224
0
        }
Unexecuted instantiation: void xmloff::OPropertyExport::exportEnumPropertyAttribute<com::sun::star::form::FormButtonType>(unsigned short, rtl::OUString const&, rtl::OUString const&, SvXMLEnumMapEntry<com::sun::star::form::FormButtonType> const*, com::sun::star::form::FormButtonType, bool)
Unexecuted instantiation: void xmloff::OPropertyExport::exportEnumPropertyAttribute<int>(unsigned short, rtl::OUString const&, rtl::OUString const&, SvXMLEnumMapEntry<int> const*, int, bool)
Unexecuted instantiation: void xmloff::OPropertyExport::exportEnumPropertyAttribute<short>(unsigned short, rtl::OUString const&, rtl::OUString const&, SvXMLEnumMapEntry<short> const*, short, bool)
Unexecuted instantiation: void xmloff::OPropertyExport::exportEnumPropertyAttribute<com::sun::star::form::ListSourceType>(unsigned short, rtl::OUString const&, rtl::OUString const&, SvXMLEnumMapEntry<com::sun::star::form::ListSourceType> const*, com::sun::star::form::ListSourceType, bool)
Unexecuted instantiation: void xmloff::OPropertyExport::exportEnumPropertyAttribute<TriState>(unsigned short, rtl::OUString const&, rtl::OUString const&, SvXMLEnumMapEntry<TriState> const*, TriState, bool)
Unexecuted instantiation: void xmloff::OPropertyExport::exportEnumPropertyAttribute<com::sun::star::form::FormSubmitEncoding>(unsigned short, rtl::OUString const&, rtl::OUString const&, SvXMLEnumMapEntry<com::sun::star::form::FormSubmitEncoding> const*, com::sun::star::form::FormSubmitEncoding, bool)
Unexecuted instantiation: void xmloff::OPropertyExport::exportEnumPropertyAttribute<com::sun::star::form::FormSubmitMethod>(unsigned short, rtl::OUString const&, rtl::OUString const&, SvXMLEnumMapEntry<com::sun::star::form::FormSubmitMethod> const*, com::sun::star::form::FormSubmitMethod, bool)
Unexecuted instantiation: void xmloff::OPropertyExport::exportEnumPropertyAttribute<com::sun::star::form::NavigationBarMode>(unsigned short, rtl::OUString const&, rtl::OUString const&, SvXMLEnumMapEntry<com::sun::star::form::NavigationBarMode> const*, com::sun::star::form::NavigationBarMode, bool)
Unexecuted instantiation: void xmloff::OPropertyExport::exportEnumPropertyAttribute<com::sun::star::form::TabulatorCycle>(unsigned short, rtl::OUString const&, rtl::OUString const&, SvXMLEnumMapEntry<com::sun::star::form::TabulatorCycle> const*, com::sun::star::form::TabulatorCycle, bool)
225
        void exportEnumPropertyAttributeImpl(
226
            const sal_uInt16 _nNamespaceKey,
227
            const OUString& _pAttributeName,
228
            const OUString& _rPropertyName,
229
            const SvXMLEnumMapEntry<sal_uInt16>* _pValueMap,
230
            const sal_uInt16 _nDefault,
231
            const bool _bVoidDefault);
232
233
        // some very special methods for some very special attribute/property pairs
234
235
        /** add the hlink:target-frame attribute to the export context.
236
237
            <p>The value of this attribute is extracted from the TargetFrame property of the object given.</p>
238
239
            <p>The property needs a special handling because conflicts between the default values for the attribute
240
            and the property.</p>
241
        */
242
        void exportTargetFrameAttribute();
243
244
        /** add the form:href attribute to the export context.
245
246
            <p>The value of this attribute is extracted from the TargetURL property of the object given.</p>
247
248
            <p>The property needs a special handling because the URL's need to be made relative</p>
249
250
            <p>If _bAddType is set, an additional xlink:type="simple" attribute is also added.</p>
251
        */
252
0
        void exportTargetLocationAttribute(bool _bAddType) { exportRelativeTargetLocation(PROPERTY_TARGETURL,CCAFlags::TargetLocation,_bAddType); }
253
254
        /** add the form:image attribute to the export context.
255
256
            <p>The value of this attribute is extracted from the ImageURL property of the object given.</p>
257
258
            <p>The property needs a special handling because the URL's need to be made relative</p>
259
        */
260
0
        void exportImageDataAttribute() { exportRelativeTargetLocation(PROPERTY_GRAPHIC, CCAFlags::ImageData, false); }
261
262
        /** flag the style properties as 'already exported'
263
264
            <p>We don't have style support right now, so the only thing the method does is removing the style-relevant
265
            properties from the list of yet-to-be-exported properties (<member>m_aRemainingProps</member>)</p>
266
        */
267
        void flagStyleProperties();
268
269
        /** add an arbitrary attribute extracted from an arbitrary property to the export context
270
271
            <p>The current value of the property specified with <arg>_pPropertyName</arg> is taken and converted
272
            into a string, no matter what type it has. (Okay, there are the usual limitations: We know Date, Datetime,
273
            double, integer ... to name just a few).</p>
274
275
            <p>In case the property value is <NULL/> (void), no attribute is added</p>
276
277
            <p>In case the property value is an empty string, and the property is a not allowed to be <NULL/> (void),
278
            no attribute is added</p>
279
280
            <p>In case the property value is a sequence of any type, no attribute is added, 'cause sequences can't be
281
            transported as attribute. In the debug version, an additional assertion will occur if you nonetheless try
282
            to do this.</p>
283
284
            @param _nNamespaceKey
285
                the key of the namespace to use for the attribute name. Is used with the namespace map
286
                provided by the export context.
287
            @param _pAttributeName
288
                the name of the attribute to add. Must not contain any namespace (it's added automatically)
289
            @param _pPropertyName
290
                the name of the property to ask the object for
291
        */
292
        void exportGenericPropertyAttribute(
293
            const sal_uInt16 _nAttributeNamespaceKey,
294
            const OUString& _pAttributeName,
295
            const OUString& _pPropertyName);
296
297
        /** exports a property value, which is a string sequence, as attribute
298
299
            <p>The elements of the string sequence given are quoted and concatenated, with the characters used for
300
            this to be chosen by the caller</p>
301
302
            <p>If you use the quote character, no check (except assertions) is made if one of the list items
303
            contains the quote character</p>
304
305
            <p>If you don't use the quote character, no check (except assertions) is made if one of the list items
306
            contains the separator character (which would be deadly when reimporting the string)</p>
307
308
            @param _nNamespaceKey
309
                the key of the namespace to use for the attribute name. Is used with the namespace map
310
                provided by the export context.
311
            @param _pAttributeName
312
                the name of the attribute to add. Must not contain any namespace (it's added automatically)
313
            @param _pPropertyName
314
                the name of the property to ask the object for
315
        */
316
        void exportStringSequenceAttribute(
317
            const sal_uInt16 _nAttributeNamespaceKey,
318
            const OUString& _pAttributeName,
319
            const OUString& _rPropertyName);
320
321
        /** determines whether the given property is to be exported
322
323
            <p>Currently, the method simply checks whether the property's state is <em>not</em> PropertyState.DEFAULT,
324
            or whether the property is a dynamic property (i.e. added via an <code>XPropertyContainer</code>).
325
            So, take care when using the method - the heuristics is not applicable for all properties.</p>
326
        */
327
        bool shouldExportProperty( const OUString& i_propertyName ) const;
328
329
        /** tries to convert an arbitrary <type scope="com.sun:star.uno">Any</type> into an string
330
331
            <p>If the type contained in the Any is not supported, the returned string will be empty. In the
332
            debug version, an additional assertion occurs.</p>
333
334
            @param  _rValue
335
                the value to convert
336
        */
337
        OUString implConvertAny(
338
            const css::uno::Any& _rValue);
339
340
        /**
341
            @return
342
                token which can be used in the <code>form:property</code> element's <code>type</code> attribute
343
                to describe the type of a value.<br/>
344
                Possible types returned are
345
                <ul>
346
                    <li><b>boolean</b>: <arg>_rValue</arg> was interpreted as boolean value before converting
347
                        it into a string</li>
348
                    <li><b>float</b>: <arg>_rValue</arg> was interpreted as 64 bit floating point 16bit integer, 32bit integer or 64 bit integer value before
349
                        converting it into a string</li>
350
                    <li><b>string</b>: <arg>_rValue</arg> did not need any conversion as it already was a string</li>
351
                </ul>
352
                If the type is not convertible, float is returned
353
        */
354
        static ::xmloff::token::XMLTokenEnum implGetPropertyXMLType(const css::uno::Type& _rType);
355
356
#ifdef DBG_UTIL
357
                void AddAttribute( sal_uInt16 _nPrefix, const OUString& _rName, const OUString& _rValue );
358
                void AddAttribute(sal_uInt16 _nPrefix, ::xmloff::token::XMLTokenEnum _eName, const OUString& _rValue);
359
                void AddAttribute(sal_uInt16 _nPrefix, ::xmloff::token::XMLTokenEnum _eName, ::xmloff::token::XMLTokenEnum _eValue );
360
#else
361
        //  in the product version, inline this, so it does not cost us extra time calling into our method
362
        void AddAttribute( sal_uInt16 _nPrefix, const OUString& _rName, const OUString& _rValue )
363
0
            { m_rContext.getGlobalContext().AddAttribute( _nPrefix, _rName, _rValue ); }
364
        void AddAttribute(sal_uInt16 _nPrefix, ::xmloff::token::XMLTokenEnum _eName, const OUString& _rValue)
365
0
            { m_rContext.getGlobalContext().AddAttribute(_nPrefix, _eName, _rValue); }
366
        void AddAttribute(sal_uInt16 _nPrefix, ::xmloff::token::XMLTokenEnum _eName, ::xmloff::token::XMLTokenEnum _eValue )
367
0
            { m_rContext.getGlobalContext().AddAttribute(_nPrefix, _eName, _eValue); }
368
#endif
369
370
#ifdef DBG_UTIL
371
    protected:
372
        /** check a given property set for the existence and type correctness of a given property
373
374
            <p>This method is available in the non-product version only.</p>
375
376
            @param _rPropertyName
377
                the name of the property to ask the control model for
378
            @param _pType
379
                the expected type of the property. May be NULL, in this case no type check is made.
380
            @return sal_True, if the property exists and is of the correct type
381
        */
382
        void dbg_implCheckProperty(
383
            const OUString& _rPropertyName,
384
            const css::uno::Type* _pType);
385
386
//      void dbg_implCheckProperty(
387
//          const char* _rPropertyName,
388
//          const css::uno::Type* _pType)
389
//      {
390
//          dbg_implCheckProperty(OUString::createFromAscii(_rPropertyName), _pType);
391
//      }
392
#endif
393
    };
394
395
    //= helper
396
#ifdef DBG_UTIL
397
    #define DBG_CHECK_PROPERTY(name, type)  \
398
        dbg_implCheckProperty(name, &cppu::UnoType<type>::get())
399
400
    #define DBG_CHECK_PROPERTY_NO_TYPE(name)    \
401
        dbg_implCheckProperty(name, nullptr)
402
403
    #define DBG_CHECK_PROPERTY_ASCII_NO_TYPE( name ) \
404
        dbg_implCheckProperty( OUString::createFromAscii( name ), nullptr )
405
#else
406
    #define DBG_CHECK_PROPERTY(name, type)
407
    #define DBG_CHECK_PROPERTY_NO_TYPE(name)
408
    #define DBG_CHECK_PROPERTY_ASCII_NO_TYPE( name )
409
#endif
410
411
}   // namespace xmloff
412
413
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */