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/elementexport.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 "elementexport.hxx"
21
22
#include "strings.hxx"
23
#include <utility>
24
#include <xmloff/xmlnamespace.hxx>
25
#include "eventexport.hxx"
26
#include "formenums.hxx"
27
#include "formcellbinding.hxx"
28
#include <xmloff/xformsexport.hxx>
29
#include "property_meta_data.hxx"
30
31
#include <com/sun/star/text/XText.hpp>
32
#include <com/sun/star/lang/XServiceInfo.hpp>
33
#include <com/sun/star/io/XPersistObject.hpp>
34
#include <com/sun/star/util/Duration.hpp>
35
#include <com/sun/star/form/FormComponentType.hpp>
36
#include <com/sun/star/form/FormSubmitEncoding.hpp>
37
#include <com/sun/star/form/FormSubmitMethod.hpp>
38
#include <com/sun/star/sdb/CommandType.hpp>
39
#include <com/sun/star/form/NavigationBarMode.hpp>
40
#include <com/sun/star/form/TabulatorCycle.hpp>
41
#include <com/sun/star/form/FormButtonType.hpp>
42
#include <com/sun/star/awt/ScrollBarOrientation.hpp>
43
#include <com/sun/star/awt/VisualEffect.hpp>
44
#include <com/sun/star/form/ListSourceType.hpp>
45
#include <com/sun/star/awt/ImagePosition.hpp>
46
47
#include <sax/tools/converter.hxx>
48
#include <tools/gen.hxx>
49
#include <xmloff/txtprmap.hxx>
50
#include <com/sun/star/form/binding/XBindableValue.hpp>
51
#include <com/sun/star/form/binding/XListEntrySink.hpp>
52
#include <tools/urlobj.hxx>
53
#include <xmloff/xmlexp.hxx>
54
#include <xmloff/namespacemap.hxx>
55
#include <xmloff/XMLEventExport.hxx>
56
#include <xmloff/xmluconv.hxx>
57
#include <xmloff/xmltoken.hxx>
58
#include <xmloff/maptype.hxx>
59
#include <tools/time.hxx>
60
#include <comphelper/diagnose_ex.hxx>
61
#include <comphelper/extract.hxx>
62
#include <sal/log.hxx>
63
64
#include <algorithm>
65
66
namespace xmloff
67
{
68
69
    #if OSL_DEBUG_LEVEL > 0
70
        #define RESET_BIT( bitfield, bit ) \
71
            bitfield = bitfield & ~bit
72
    #else
73
        #define RESET_BIT( bitfield, bit )
74
    #endif
75
76
    using namespace ::xmloff::token;
77
    using namespace ::com::sun::star;
78
    using namespace ::com::sun::star::uno;
79
    using namespace ::com::sun::star::sdb;
80
    using namespace ::com::sun::star::awt;
81
    using namespace ::com::sun::star::form;
82
    using namespace ::com::sun::star::lang;
83
    using namespace ::com::sun::star::beans;
84
    using namespace ::com::sun::star::container;
85
    using namespace ::com::sun::star::script;
86
    using namespace ::com::sun::star::io;
87
    using namespace ::com::sun::star::text;
88
    using namespace ::com::sun::star::form::binding;
89
90
    //= OElementExport
91
    OElementExport::OElementExport(IFormsExportContext& _rContext, const Reference< XPropertySet >& _rxProps,
92
        const Sequence< ScriptEventDescriptor >& _rEvents)
93
0
        :OPropertyExport(_rContext, _rxProps)
94
0
        ,m_aEvents(_rEvents)
95
0
    {
96
0
    }
97
98
    OElementExport::~OElementExport()
99
0
    {
100
0
    }
101
102
    void OElementExport::doExport()
103
0
    {
104
        // collect some general information about the element
105
0
        examine();
106
107
        // first add the attributes necessary for the element
108
0
        m_rContext.getGlobalContext().ClearAttrList();
109
110
        // add the attributes
111
0
        exportAttributes();
112
113
        // start the XML element
114
0
        implStartElement(getXMLElementName());
115
116
        // the sub elements (mostly control type dependent)
117
0
        exportSubTags();
118
119
0
        implEndElement();
120
0
    }
121
122
    void OElementExport::examine()
123
0
    {
124
        // nothing to do here
125
0
    }
126
127
    void OElementExport::exportAttributes()
128
0
    {
129
        // nothing to do here
130
0
    }
131
132
    void OElementExport::exportSubTags()
133
0
    {
134
        // the properties which where not exported 'til now
135
0
        exportRemainingProperties();
136
137
        // the script:events sub tags
138
0
        exportEvents();
139
0
    }
140
141
    void OElementExport::implStartElement(const OUString& _pName)
142
0
    {
143
0
        m_pXMLElement = std::make_unique<SvXMLElementExport>(m_rContext.getGlobalContext(), XML_NAMESPACE_FORM, _pName, true, true);
144
0
    }
145
146
    void OElementExport::implEndElement()
147
0
    {
148
0
        m_pXMLElement.reset();
149
0
    }
150
151
    void OElementExport::exportServiceNameAttribute()
152
0
    {
153
0
        Reference< XPersistObject > xPersistence(m_xProps, UNO_QUERY);
154
0
        if (!xPersistence.is())
155
0
        {
156
0
            OSL_FAIL("OElementExport::exportServiceNameAttribute: no XPersistObject!");
157
0
            return;
158
0
        }
159
160
0
        OUString sServiceName = xPersistence->getServiceName();
161
        // we don't want to write the old service name directly: it's a name used for compatibility reasons, but
162
        // as we start some kind of new file format here (with this xml export), we don't care about
163
        // compatibility ...
164
        // So we translate the old persistence service name into new ones, if possible
165
166
0
        OUString sToWriteServiceName = sServiceName;
167
0
#define CHECK_N_TRANSLATE( persistentComponent, serviceName )   \
168
0
        else if (sServiceName == persistentComponent) \
169
0
            sToWriteServiceName = serviceName
170
171
0
        if (sServiceName == SERVICE_PERSISTENT_COMPONENT_EDIT)
172
0
        {
173
            // special handling for the edit field: we have two controls using this as persistence service name
174
0
            sToWriteServiceName = SERVICE_EDIT;
175
0
            Reference< XServiceInfo > xSI(m_xProps, UNO_QUERY);
176
0
            if (xSI.is() && xSI->supportsService(SERVICE_FORMATTEDFIELD))
177
0
                sToWriteServiceName = SERVICE_FORMATTEDFIELD;
178
0
        }
179
0
        CHECK_N_TRANSLATE( SERVICE_PERSISTENT_COMPONENT_FORM,           SERVICE_FORM );
180
0
        CHECK_N_TRANSLATE( SERVICE_PERSISTENT_COMPONENT_LISTBOX,        SERVICE_LISTBOX );
181
0
        CHECK_N_TRANSLATE( SERVICE_PERSISTENT_COMPONENT_COMBOBOX,       SERVICE_COMBOBOX );
182
0
        CHECK_N_TRANSLATE( SERVICE_PERSISTENT_COMPONENT_RADIOBUTTON,    SERVICE_RADIOBUTTON );
183
0
        CHECK_N_TRANSLATE( SERVICE_PERSISTENT_COMPONENT_GROUPBOX,       SERVICE_GROUPBOX );
184
0
        CHECK_N_TRANSLATE( SERVICE_PERSISTENT_COMPONENT_FIXEDTEXT,      SERVICE_FIXEDTEXT );
185
0
        CHECK_N_TRANSLATE( SERVICE_PERSISTENT_COMPONENT_COMMANDBUTTON,  SERVICE_COMMANDBUTTON );
186
0
        CHECK_N_TRANSLATE( SERVICE_PERSISTENT_COMPONENT_CHECKBOX,       SERVICE_CHECKBOX );
187
0
        CHECK_N_TRANSLATE( SERVICE_PERSISTENT_COMPONENT_GRID,           SERVICE_GRID );
188
0
        CHECK_N_TRANSLATE( SERVICE_PERSISTENT_COMPONENT_IMAGEBUTTON,    SERVICE_IMAGEBUTTON );
189
0
        CHECK_N_TRANSLATE( SERVICE_PERSISTENT_COMPONENT_FILECONTROL,    SERVICE_FILECONTROL );
190
0
        CHECK_N_TRANSLATE( SERVICE_PERSISTENT_COMPONENT_TIMEFIELD,      SERVICE_TIMEFIELD );
191
0
        CHECK_N_TRANSLATE( SERVICE_PERSISTENT_COMPONENT_DATEFIELD,      SERVICE_DATEFIELD );
192
0
        CHECK_N_TRANSLATE( SERVICE_PERSISTENT_COMPONENT_NUMERICFIELD,   SERVICE_NUMERICFIELD );
193
0
        CHECK_N_TRANSLATE( SERVICE_PERSISTENT_COMPONENT_CURRENCYFIELD,  SERVICE_CURRENCYFIELD );
194
0
        CHECK_N_TRANSLATE( SERVICE_PERSISTENT_COMPONENT_PATTERNFIELD,   SERVICE_PATTERNFIELD );
195
0
        CHECK_N_TRANSLATE( SERVICE_PERSISTENT_COMPONENT_HIDDENCONTROL,  SERVICE_HIDDENCONTROL );
196
0
        CHECK_N_TRANSLATE( SERVICE_PERSISTENT_COMPONENT_IMAGECONTROL,   SERVICE_IMAGECONTROL );
197
0
        CHECK_N_TRANSLATE( SERVICE_PERSISTENT_COMPONENT_FORMATTEDFIELD, SERVICE_FORMATTEDFIELD );
198
#if OSL_DEBUG_LEVEL > 0
199
        Reference< XServiceInfo > xSI(m_xProps, UNO_QUERY);
200
        OSL_ENSURE(xSI.is() && xSI->supportsService(sToWriteServiceName),
201
            "OElementExport::exportServiceNameAttribute: wrong service name translation!");
202
203
#endif
204
0
        sToWriteServiceName =
205
0
            m_rContext.getGlobalContext().GetNamespaceMap().GetQNameByKey(
206
0
                XML_NAMESPACE_OOO, sToWriteServiceName );
207
208
        // now write this
209
0
        AddAttribute(
210
0
            OAttributeMetaData::getCommonControlAttributeNamespace(CCAFlags::ServiceName),
211
0
            OAttributeMetaData::getCommonControlAttributeName(CCAFlags::ServiceName),
212
0
            sToWriteServiceName);
213
0
    }
214
215
    void OElementExport::exportEvents()
216
0
    {
217
0
        if (!m_aEvents.hasElements())
218
            // nothing to do
219
0
            return;
220
221
0
        Reference< XNameReplace > xWrapper = new OEventDescriptorMapper(m_aEvents);
222
0
        m_rContext.getGlobalContext().GetEventExport().Export(xWrapper);
223
0
    }
224
225
    //= OControlExport
226
    OControlExport::OControlExport(IFormsExportContext& _rContext,  const Reference< XPropertySet >& _rxControl,
227
        OUString _sControlId, OUString _sReferringControls,
228
        const Sequence< ScriptEventDescriptor >& _rEvents)
229
0
        :OElementExport(_rContext, _rxControl, _rEvents)
230
0
        ,m_sControlId(std::move(_sControlId))
231
0
        ,m_sReferringControls(std::move(_sReferringControls))
232
0
        ,m_nClassId(FormComponentType::CONTROL)
233
0
        ,m_eType( UNKNOWN )
234
0
        ,m_nIncludeCommon(CCAFlags::NONE)
235
0
        ,m_nIncludeDatabase(DAFlags::NONE)
236
0
        ,m_nIncludeSpecial(SCAFlags::NONE)
237
0
        ,m_nIncludeEvents(EAFlags::NONE)
238
0
        ,m_nIncludeBindings(BAFlags::NONE)
239
0
    {
240
0
        OSL_ENSURE(m_xProps.is(), "OControlExport::OControlExport: invalid arguments!");
241
0
    }
242
243
    void OControlExport::exportOuterAttributes()
244
0
    {
245
        // the control id
246
0
        if (CCAFlags::Name & m_nIncludeCommon)
247
0
        {
248
0
            exportStringPropertyAttribute(
249
0
                OAttributeMetaData::getCommonControlAttributeNamespace(CCAFlags::Name),
250
0
                OAttributeMetaData::getCommonControlAttributeName(CCAFlags::Name),
251
0
                PROPERTY_NAME
252
0
                );
253
        #if OSL_DEBUG_LEVEL > 0
254
            //  reset the bit for later checking
255
            m_nIncludeCommon = m_nIncludeCommon & ~CCAFlags::Name;
256
        #endif
257
0
        }
258
259
        // the service name
260
0
        if (m_nIncludeCommon & CCAFlags::ServiceName)
261
0
        {
262
0
            exportServiceNameAttribute();
263
        #if OSL_DEBUG_LEVEL > 0
264
            //  reset the bit for later checking
265
            m_nIncludeCommon = m_nIncludeCommon & ~CCAFlags::ServiceName;
266
        #endif
267
0
        }
268
0
    }
269
270
    void OControlExport::exportInnerAttributes()
271
0
    {
272
        // the control id
273
0
        if (CCAFlags::ControlId & m_nIncludeCommon)
274
0
        {
275
0
            OSL_ENSURE(!m_sControlId.isEmpty(), "OControlExport::exportInnerAttributes: have no control id for the control!");
276
0
            m_rContext.getGlobalContext().AddAttributeIdLegacy(
277
0
                XML_NAMESPACE_FORM, m_sControlId);
278
        #if OSL_DEBUG_LEVEL > 0
279
            //  reset the bit for later checking
280
            m_nIncludeCommon = m_nIncludeCommon & ~CCAFlags::ControlId;
281
        #endif
282
0
        }
283
284
        // "new-style" properties ...
285
0
        exportGenericHandlerAttributes();
286
287
        // common control attributes
288
0
        exportCommonControlAttributes();
289
290
        // common database attributes
291
0
        exportDatabaseAttributes();
292
293
        // attributes related to external bindings
294
0
        exportBindingAttributes();
295
296
        // attributes special to the respective control type
297
0
        exportSpecialAttributes();
298
299
        // add the style references to the attributes
300
0
        flagStyleProperties();
301
0
    }
302
303
    void OControlExport::exportAttributes()
304
0
    {
305
0
        exportOuterAttributes();
306
0
    }
307
308
    void OControlExport::exportSubTags()
309
0
    {
310
        // for the upcoming exportRemainingProperties:
311
        // if a control has the LabelControl property, this is not stored with the control itself, but instead with
312
        // the control which is referenced by this property. As the base class' exportRemainingProperties doesn't
313
        // know anything about this, we need to prevent that it tries to export this property
314
0
        exportedProperty(PROPERTY_CONTROLLABEL);
315
316
        // if it's a control supporting XText, then we need to declare all text-related properties
317
        // as "already exported". This prevents them from being exported as generic "form:property"-tags.
318
        // *If* we would export them this way, they would be completely superfluous, and sometimes even
319
        // disastrous, since they may, at import time, override paragraph properties which already have
320
        // been set before
321
0
        Reference< XText > xControlText( m_xProps, UNO_QUERY );
322
0
        if ( xControlText.is() )
323
0
        {
324
0
            const XMLPropertyMapEntry* pCharAttributeProperties = XMLTextPropertySetMapper::getPropertyMapForType( TextPropMap::TEXT );
325
0
            while ( !pCharAttributeProperties->IsEnd() )
326
0
            {
327
0
                exportedProperty( pCharAttributeProperties->getApiName() );
328
0
                ++pCharAttributeProperties;
329
0
            }
330
331
0
            const XMLPropertyMapEntry* pParaAttributeProperties = XMLTextPropertySetMapper::getPropertyMapForType( TextPropMap::SHAPE_PARA );
332
0
            while ( !pParaAttributeProperties->IsEnd() )
333
0
            {
334
0
                exportedProperty( pParaAttributeProperties->getApiName() );
335
0
                ++pParaAttributeProperties;
336
0
            }
337
338
            // the RichText property is not exported. The presence of the text:p element
339
            // will be used - upon reading - as indicator for the value of the RichText property
340
0
            exportedProperty( PROPERTY_RICH_TEXT );
341
342
            // strange thing: paragraphs support both a CharStrikeout and a CharCrossedOut property
343
            // The former is a short/enum value, the latter a boolean. The former has a real meaning
344
            // (the strikeout type), the latter hasn't. But, when the CharCrossedOut is exported and
345
            // later on imported, it overwrites anything which has previously been imported for
346
            // CharStrikeout.
347
            // #i27729#
348
0
            exportedProperty( u"CharCrossedOut"_ustr );
349
0
        }
350
351
0
        if ( m_eType == LISTBOX )
352
0
        {
353
            // will be exported in exportListSourceAsElements:
354
0
            if ( controlHasUserSuppliedListEntries() )
355
0
                exportedProperty( PROPERTY_DEFAULT_SELECT_SEQ );
356
357
            // will not be exported in a generic way. Either exportListSourceAsElements cares
358
            // for them, or we don't need them
359
0
            exportedProperty( PROPERTY_STRING_ITEM_LIST );
360
0
            exportedProperty( PROPERTY_VALUE_SEQ );
361
0
            exportedProperty( PROPERTY_SELECT_SEQ );
362
0
            exportedProperty( PROPERTY_LISTSOURCE );
363
0
        }
364
0
        if ( m_eType == COMBOBOX )
365
0
            exportedProperty( PROPERTY_STRING_ITEM_LIST );
366
367
        // let the base class export the remaining properties and the events
368
0
        OElementExport::exportSubTags();
369
370
        // special sub tags for some controls
371
0
        switch (m_eType)
372
0
        {
373
0
            case LISTBOX:
374
                // don't export the list entries if the are not provided by the user, but obtained implicitly
375
                // from other sources
376
                // #i26944#
377
0
                if ( controlHasUserSuppliedListEntries() )
378
0
                    exportListSourceAsElements();
379
0
                break;
380
0
            case GRID:
381
0
            {   // a grid control requires us to store all columns as sub elements
382
0
                Reference< XIndexAccess > xColumnContainer(m_xProps, UNO_QUERY);
383
0
                OSL_ENSURE(xColumnContainer.is(), "OControlExport::exportSubTags: a grid control which is no IndexAccess?!!");
384
0
                if (xColumnContainer.is())
385
0
                    m_rContext.exportCollectionElements(xColumnContainer);
386
0
            }
387
0
            break;
388
0
            case COMBOBOX:
389
0
            {   // a combox box description has sub elements: the items
390
0
                DBG_CHECK_PROPERTY( PROPERTY_STRING_ITEM_LIST, Sequence< OUString > );
391
392
                // don't export the list entries if the are not provided by the user, but obtained implicitly
393
                // from other sources
394
                // #i26944#
395
0
                if ( controlHasUserSuppliedListEntries() )
396
0
                {
397
                    // get the item list
398
0
                    Sequence< OUString > aListItems;
399
0
                    m_xProps->getPropertyValue(PROPERTY_STRING_ITEM_LIST) >>= aListItems;
400
                    // loop through it and write the sub elements
401
0
                    for (const auto& rListItem : aListItems)
402
0
                    {
403
0
                        m_rContext.getGlobalContext().ClearAttrList();
404
0
                        AddAttribute(
405
0
                            OAttributeMetaData::getCommonControlAttributeNamespace(CCAFlags::Label),
406
0
                            OAttributeMetaData::getCommonControlAttributeName(CCAFlags::Label),
407
0
                            rListItem);
408
0
                        SvXMLElementExport aFormElement(m_rContext.getGlobalContext(), XML_NAMESPACE_FORM, u"item"_ustr, true, true);
409
0
                    }
410
0
                }
411
0
            }
412
0
            break;
413
414
0
            case TEXT_AREA:
415
0
            {
416
                // if we act as rich text control, we need to export some text:p elements
417
0
                if ( xControlText.is() )
418
0
                {
419
0
                    bool bActingAsRichText = false;
420
0
                    if ( m_xPropertyInfo->hasPropertyByName( PROPERTY_RICH_TEXT ) )
421
0
                    {
422
0
                        OSL_VERIFY(m_xProps->getPropertyValue( PROPERTY_RICH_TEXT ) >>= bActingAsRichText );
423
0
                    }
424
425
0
                    if ( bActingAsRichText )
426
0
                        m_rContext.getGlobalContext().GetTextParagraphExport()->exportText( xControlText );
427
0
                }
428
0
            }
429
0
            break;
430
0
            default:
431
                // nothing do to
432
0
                break;
433
0
        }
434
0
    }
435
436
    void OControlExport::exportGenericHandlerAttributes()
437
0
    {
438
0
        const Sequence< Property > aProperties = m_xPropertyInfo->getProperties();
439
0
        for ( auto const & prop : aProperties )
440
0
        {
441
0
            try
442
0
            {
443
                // see if this property can already be handled with an IPropertyHandler (which, on the long
444
                // term, should be the case for most, if not all, properties)
445
0
                const PropertyDescription* propDescription = metadata::getPropertyDescription( prop.Name );
446
0
                if ( propDescription == nullptr )
447
0
                    continue;
448
449
                // let the factory provide the concrete handler. Note that caching, if desired, is the task
450
                // of the factory
451
0
                PPropertyHandler handler = (*propDescription->factory)( propDescription->propertyId );
452
0
                if ( !handler )
453
0
                {
454
0
                    SAL_WARN( "xmloff.forms", "OControlExport::exportGenericHandlerAttributes: invalid property handler provided by the factory!" );
455
0
                    continue;
456
0
                }
457
458
                // that's a property which has a direct mapping to an attribute
459
0
                if ( !shouldExportProperty( prop.Name ) )
460
                    // TODO: in the future, we surely need a more sophisticated approach to this, involving the property
461
                    // handler, or the property description
462
0
                {
463
0
                    exportedProperty( prop.Name );
464
0
                    continue;
465
0
                }
466
467
0
                const Any propValue = m_xProps->getPropertyValue( prop.Name );
468
0
                OUString attributeValue = handler->getAttributeValue( propValue );
469
470
0
                AddAttribute(
471
0
                    propDescription->attribute.namespacePrefix,
472
0
                    token::GetXMLToken( propDescription->attribute.attributeToken ),
473
0
                    attributeValue
474
0
                );
475
476
0
                exportedProperty( prop.Name );
477
0
            }
478
0
            catch( const Exception& )
479
0
            {
480
0
                DBG_UNHANDLED_EXCEPTION("xmloff.forms");
481
0
            }
482
0
        }
483
0
    }
484
485
    void OControlExport::exportCommonControlAttributes()
486
0
    {
487
0
        size_t i=0;
488
489
        // I decided to handle all the properties here with some static arrays describing the property-attribute
490
        // relations. This leads to somewhat ugly code :), but the only alternative I can think of right now
491
        // would require maps and O(log n) searches, which seems somewhat expensive as this code is used
492
        // very frequently.
493
494
        // the extra indents for the respective blocks are to ensure that there is no copy'n'paste error, using
495
        // map identifiers from the wrong block
496
497
        // some string properties
498
0
        {
499
            // the attribute ids of all properties which are expected to be of type string
500
0
            static const CCAFlags nStringPropertyAttributeIds[] =
501
0
            {
502
0
                CCAFlags::Label, CCAFlags::Title
503
0
            };
504
            // the names of all properties which are expected to be of type string
505
0
            static constexpr OUString aStringPropertyNames[] =
506
0
            {
507
0
                PROPERTY_LABEL, PROPERTY_TITLE
508
0
            };
509
0
            OSL_ENSURE( std::size(aStringPropertyNames) ==
510
0
                        std::size(nStringPropertyAttributeIds),
511
0
                        "OControlExport::exportCommonControlAttributes: somebody tampered with the maps (1)!");
512
513
0
            for (i=0; i<std::size(nStringPropertyAttributeIds); ++i)
514
0
                if (nStringPropertyAttributeIds[i] & m_nIncludeCommon)
515
0
                {
516
0
                    exportStringPropertyAttribute(
517
0
                        OAttributeMetaData::getCommonControlAttributeNamespace(nStringPropertyAttributeIds[i]),
518
0
                        OAttributeMetaData::getCommonControlAttributeName(nStringPropertyAttributeIds[i]),
519
0
                        aStringPropertyNames[i]
520
0
                        );
521
                #if OSL_DEBUG_LEVEL > 0
522
                    //  reset the bit for later checking
523
                    m_nIncludeCommon = m_nIncludeCommon & ~nStringPropertyAttributeIds[i];
524
                #endif
525
0
                }
526
0
        }
527
528
        // some boolean properties
529
0
        {
530
0
            static const CCAFlags nBooleanPropertyAttributeIds[] =
531
0
            {   // attribute flags
532
0
                CCAFlags::CurrentSelected, CCAFlags::Disabled, CCAFlags::Dropdown, CCAFlags::Printable, CCAFlags::ReadOnly, CCAFlags::Selected, CCAFlags::TabStop, CCAFlags::EnableVisible
533
0
            };
534
0
            static constexpr OUString pBooleanPropertyNames[] =
535
0
            {   // property names
536
0
                PROPERTY_STATE, PROPERTY_ENABLED,
537
0
                PROPERTY_DROPDOWN, PROPERTY_PRINTABLE,
538
0
                PROPERTY_READONLY, PROPERTY_DEFAULT_STATE,
539
0
                PROPERTY_TABSTOP, PROPERTY_ENABLEVISIBLE
540
0
            };
541
0
            static const BoolAttrFlags nBooleanPropertyAttrFlags[] =
542
0
            {   // attribute defaults
543
0
                BoolAttrFlags::DefaultFalse, BoolAttrFlags::DefaultFalse | BoolAttrFlags::InverseSemantics, BoolAttrFlags::DefaultFalse, BoolAttrFlags::DefaultTrue, BoolAttrFlags::DefaultFalse, BoolAttrFlags::DefaultFalse, BoolAttrFlags::DefaultVoid, BoolAttrFlags::DefaultFalse
544
0
            };
545
        #if OSL_DEBUG_LEVEL > 0
546
            static const sal_Int32 nIdCount = std::size(nBooleanPropertyAttributeIds);
547
            static const sal_Int32 nNameCount = std::size(pBooleanPropertyNames);
548
            static const sal_Int32 nFlagsCount = std::size(nBooleanPropertyAttrFlags);
549
            OSL_ENSURE((nIdCount == nNameCount) && (nNameCount == nFlagsCount),
550
                "OControlExport::exportCommonControlAttributes: somebody tampered with the maps (2)!");
551
        #endif
552
0
            for (i=0; i<std::size(nBooleanPropertyAttributeIds); ++i)
553
0
                if (nBooleanPropertyAttributeIds[i] & m_nIncludeCommon)
554
0
                {
555
0
                    exportBooleanPropertyAttribute(
556
0
                        OAttributeMetaData::getCommonControlAttributeNamespace(nBooleanPropertyAttributeIds[i]),
557
0
                        OAttributeMetaData::getCommonControlAttributeName(nBooleanPropertyAttributeIds[i]),
558
0
                        pBooleanPropertyNames[i],
559
0
                        nBooleanPropertyAttrFlags[i]);
560
        #if OSL_DEBUG_LEVEL > 0
561
                    //  reset the bit for later checking
562
                    m_nIncludeCommon = m_nIncludeCommon & ~nBooleanPropertyAttributeIds[i];
563
        #endif
564
0
                }
565
0
        }
566
567
        // some integer properties
568
0
        {
569
            // now the common handling
570
0
            static const CCAFlags nIntegerPropertyAttributeIds[] =
571
0
            {   // attribute flags
572
0
                CCAFlags::Size, CCAFlags::TabIndex
573
0
            };
574
0
            static constexpr OUString pIntegerPropertyNames[] =
575
0
            {   // property names
576
0
                PROPERTY_LINECOUNT, PROPERTY_TABINDEX
577
0
            };
578
0
            static const sal_Int16 nIntegerPropertyAttrDefaults[] =
579
0
            {   // attribute defaults
580
0
                5, 0
581
0
            };
582
583
0
            if ( m_nIncludeCommon & CCAFlags::MaxLength )
584
0
                exportedProperty(PROPERTY_MAXTEXTLENGTH);
585
586
        #if OSL_DEBUG_LEVEL > 0
587
            static const sal_Int32 nIdCount = std::size(nIntegerPropertyAttributeIds);
588
            static const sal_Int32 nNameCount = std::size(pIntegerPropertyNames);
589
            static const sal_Int32 nDefaultCount = std::size(nIntegerPropertyAttrDefaults);
590
            OSL_ENSURE((nIdCount == nNameCount) && (nNameCount == nDefaultCount),
591
                "OControlExport::exportCommonControlAttributes: somebody tampered with the maps (3)!");
592
        #endif
593
0
            for (i=0; i<std::size(nIntegerPropertyAttributeIds); ++i)
594
0
                if (nIntegerPropertyAttributeIds[i] & m_nIncludeCommon)
595
0
                {
596
0
                    exportInt16PropertyAttribute(
597
0
                        OAttributeMetaData::getCommonControlAttributeNamespace(nIntegerPropertyAttributeIds[i]),
598
0
                        OAttributeMetaData::getCommonControlAttributeName(nIntegerPropertyAttributeIds[i]),
599
0
                        pIntegerPropertyNames[i],
600
0
                        nIntegerPropertyAttrDefaults[i]);
601
        #if OSL_DEBUG_LEVEL > 0
602
                    //  reset the bit for later checking
603
                    m_nIncludeCommon = m_nIncludeCommon & ~nIntegerPropertyAttributeIds[i];
604
        #endif
605
0
                }
606
607
0
        }
608
609
        // some enum properties
610
0
        {
611
0
            if (m_nIncludeCommon & CCAFlags::ButtonType)
612
0
            {
613
0
                exportEnumPropertyAttribute(
614
0
                    OAttributeMetaData::getCommonControlAttributeNamespace(CCAFlags::ButtonType),
615
0
                    OAttributeMetaData::getCommonControlAttributeName(CCAFlags::ButtonType),
616
0
                    PROPERTY_BUTTONTYPE,
617
0
                    aFormButtonTypeMap,
618
0
                    FormButtonType_PUSH);
619
        #if OSL_DEBUG_LEVEL > 0
620
                //  reset the bit for later checking
621
                m_nIncludeCommon = m_nIncludeCommon & ~CCAFlags::ButtonType;
622
        #endif
623
0
            }
624
0
            if ( m_nIncludeCommon & CCAFlags::Orientation )
625
0
            {
626
0
                exportEnumPropertyAttribute(
627
0
                    OAttributeMetaData::getCommonControlAttributeNamespace( CCAFlags::Orientation ),
628
0
                    OAttributeMetaData::getCommonControlAttributeName( CCAFlags::Orientation ),
629
0
                    PROPERTY_ORIENTATION,
630
0
                    aOrientationMap,
631
0
                    ScrollBarOrientation::HORIZONTAL
632
0
                );
633
        #if OSL_DEBUG_LEVEL > 0
634
                //  reset the bit for later checking
635
                m_nIncludeCommon = m_nIncludeCommon & ~CCAFlags::Orientation;
636
        #endif
637
0
            }
638
639
0
            if ( m_nIncludeCommon & CCAFlags::VisualEffect )
640
0
            {
641
0
                exportEnumPropertyAttribute(
642
0
                    OAttributeMetaData::getCommonControlAttributeNamespace( CCAFlags::VisualEffect ),
643
0
                    OAttributeMetaData::getCommonControlAttributeName( CCAFlags::VisualEffect ),
644
0
                    PROPERTY_VISUAL_EFFECT,
645
0
                    aVisualEffectMap,
646
0
                    VisualEffect::LOOK3D
647
0
                );
648
            #if OSL_DEBUG_LEVEL > 0
649
                //  reset the bit for later checking
650
                m_nIncludeCommon = m_nIncludeCommon & ~CCAFlags::VisualEffect;
651
            #endif
652
0
            }
653
0
        }
654
655
        // some properties which require a special handling
656
657
        // the target frame
658
0
        if (m_nIncludeCommon & CCAFlags::TargetFrame)
659
0
        {
660
0
            exportTargetFrameAttribute();
661
        #if OSL_DEBUG_LEVEL > 0
662
            //  reset the bit for later checking
663
            m_nIncludeCommon = m_nIncludeCommon & ~CCAFlags::TargetFrame;
664
        #endif
665
0
        }
666
667
        // max text length
668
0
        if ( m_nIncludeCommon & CCAFlags::MaxLength )
669
0
        {
670
            // normally, the respective property would be "MaxTextLen"
671
            // However, if the model has a property "PersistenceMaxTextLength", then we prefer this
672
673
            // determine the name of the property to export
674
0
            OUString sTextLenPropertyName( PROPERTY_MAXTEXTLENGTH );
675
0
            if ( m_xPropertyInfo->hasPropertyByName( PROPERTY_PERSISTENCE_MAXTEXTLENGTH ) )
676
0
                sTextLenPropertyName = PROPERTY_PERSISTENCE_MAXTEXTLENGTH;
677
678
            // export it
679
0
            exportInt16PropertyAttribute(
680
0
                OAttributeMetaData::getCommonControlAttributeNamespace( CCAFlags::MaxLength ),
681
0
                OAttributeMetaData::getCommonControlAttributeName( CCAFlags::MaxLength ),
682
0
                sTextLenPropertyName,
683
0
                0
684
0
            );
685
686
            // in either way, both properties count as "exported"
687
0
            exportedProperty( PROPERTY_MAXTEXTLENGTH );
688
0
            exportedProperty( PROPERTY_PERSISTENCE_MAXTEXTLENGTH );
689
690
        #if OSL_DEBUG_LEVEL > 0
691
            //  reset the bit for later checking
692
            m_nIncludeCommon = m_nIncludeCommon & ~CCAFlags::MaxLength;
693
        #endif
694
0
        }
695
696
0
        if (m_nIncludeCommon & CCAFlags::TargetLocation)
697
0
        {
698
0
            exportTargetLocationAttribute(false);
699
        #if OSL_DEBUG_LEVEL > 0
700
            //  reset the bit for later checking
701
            m_nIncludeCommon = m_nIncludeCommon & ~CCAFlags::TargetLocation;
702
        #endif
703
0
        }
704
705
        // OJ #99721#
706
0
        if (m_nIncludeCommon & CCAFlags::ImageData)
707
0
        {
708
0
            exportImageDataAttribute();
709
        #if OSL_DEBUG_LEVEL > 0
710
            //  reset the bit for later checking
711
            m_nIncludeCommon = m_nIncludeCommon & ~CCAFlags::ImageData;
712
        #endif
713
0
        }
714
715
        // the for attribute
716
        // the target frame
717
0
        if (m_nIncludeCommon & CCAFlags::For)
718
0
        {
719
0
            if (!m_sReferringControls.isEmpty())
720
0
            {   // there is at least one control referring to the one we're handling currently
721
0
                AddAttribute(
722
0
                    OAttributeMetaData::getCommonControlAttributeNamespace(CCAFlags::For),
723
0
                    OAttributeMetaData::getCommonControlAttributeName(CCAFlags::For),
724
0
                    m_sReferringControls);
725
0
            }
726
        #if OSL_DEBUG_LEVEL > 0
727
            //  reset the bit for later checking
728
            m_nIncludeCommon = m_nIncludeCommon & ~CCAFlags::For;
729
        #endif
730
0
        }
731
732
0
        if ((CCAFlags::CurrentValue | CCAFlags::Value) & m_nIncludeCommon)
733
0
        {
734
0
            OUString pCurrentValuePropertyName;
735
0
            OUString pValuePropertyName;
736
737
            // get the property names
738
0
            getValuePropertyNames(m_eType, m_nClassId, pCurrentValuePropertyName, pValuePropertyName);
739
740
            // add the attributes if necessary and possible
741
0
            if (!pCurrentValuePropertyName.isEmpty() && (CCAFlags::CurrentValue & m_nIncludeCommon))
742
0
            {
743
0
                static const OUString pCurrentValueAttributeName = OAttributeMetaData::getCommonControlAttributeName(CCAFlags::CurrentValue);
744
                // don't export the current-value if this value originates from a data binding
745
                // #i26944#
746
0
                if ( controlHasActiveDataBinding() )
747
0
                    exportedProperty( pCurrentValuePropertyName );
748
0
                else
749
0
                {
750
0
                    static const sal_uInt16 nCurrentValueAttributeNamespaceKey = OAttributeMetaData::getCommonControlAttributeNamespace(CCAFlags::CurrentValue);
751
0
                    exportGenericPropertyAttribute(
752
0
                        nCurrentValueAttributeNamespaceKey,
753
0
                        pCurrentValueAttributeName,
754
0
                        pCurrentValuePropertyName
755
0
                    );
756
0
                }
757
0
            }
758
759
0
            if (!pValuePropertyName.isEmpty() && (CCAFlags::Value & m_nIncludeCommon))
760
0
            {
761
0
                static const OUString pValueAttributeName = OAttributeMetaData::getCommonControlAttributeName(CCAFlags::Value);
762
0
                static const sal_uInt16 nValueAttributeNamespaceKey = OAttributeMetaData::getCommonControlAttributeNamespace(CCAFlags::Value);
763
0
                exportGenericPropertyAttribute(
764
0
                    nValueAttributeNamespaceKey,
765
0
                    pValueAttributeName,
766
0
                    pValuePropertyName);
767
0
            }
768
769
0
            OSL_ENSURE((pValuePropertyName.isEmpty()) == (CCAFlags::NONE == (CCAFlags::Value & m_nIncludeCommon)),
770
0
                "OControlExport::exportCommonControlAttributes: no property found for the value attribute!");
771
0
            OSL_ENSURE((pCurrentValuePropertyName.isEmpty()) == (CCAFlags::NONE == (CCAFlags::CurrentValue & m_nIncludeCommon)),
772
0
                "OControlExport::exportCommonControlAttributes: no property found for the current-value attribute!");
773
774
        #if OSL_DEBUG_LEVEL > 0
775
            //  reset the bit for later checking
776
            m_nIncludeCommon = m_nIncludeCommon & ~CCAFlags(CCAFlags::CurrentValue | CCAFlags::Value);
777
        #endif
778
0
        }
779
780
0
        OSL_ENSURE(CCAFlags::NONE == m_nIncludeCommon,
781
0
            "OControlExport::exportCommonControlAttributes: forgot some flags!");
782
            // in the dbg_util version, we should have removed every bit we handled from the mask, so it should
783
            // be 0 now ...
784
0
    }
785
786
    void OControlExport::exportDatabaseAttributes()
787
0
    {
788
#if OSL_DEBUG_LEVEL > 0
789
        DAFlags nIncludeDatabase = m_nIncludeDatabase;
790
#endif
791
        // the only string property: DataField
792
0
        if (DAFlags::DataField & m_nIncludeDatabase)
793
0
        {
794
0
            exportStringPropertyAttribute(
795
0
                OAttributeMetaData::getDatabaseAttributeNamespace(),
796
0
                OAttributeMetaData::getDatabaseAttributeName(DAFlags::DataField),
797
0
                PROPERTY_DATAFIELD);
798
0
            RESET_BIT( nIncludeDatabase, DAFlags::DataField );
799
0
        }
800
801
        // InputRequired
802
0
        if ( DAFlags::InputRequired & m_nIncludeDatabase )
803
0
        {
804
0
            exportBooleanPropertyAttribute(
805
0
                OAttributeMetaData::getDatabaseAttributeNamespace(),
806
0
                OAttributeMetaData::getDatabaseAttributeName( DAFlags::InputRequired ),
807
0
                PROPERTY_INPUT_REQUIRED,
808
0
                BoolAttrFlags::DefaultFalse | BoolAttrFlags::DefaultVoid
809
0
            );
810
0
            RESET_BIT( nIncludeDatabase, DAFlags::InputRequired );
811
0
        }
812
813
        // the only int16 property: BoundColumn
814
0
        if (DAFlags::BoundColumn & m_nIncludeDatabase)
815
0
        {
816
0
            exportInt16PropertyAttribute(
817
0
                OAttributeMetaData::getDatabaseAttributeNamespace(),
818
0
                OAttributeMetaData::getDatabaseAttributeName(DAFlags::BoundColumn),
819
0
                PROPERTY_BOUNDCOLUMN,
820
0
                0,
821
0
                true);
822
0
            RESET_BIT( nIncludeDatabase, DAFlags::BoundColumn );
823
0
        }
824
825
        // ConvertEmptyToNull
826
0
        if (DAFlags::ConvertEmpty & m_nIncludeDatabase)
827
0
        {
828
0
            exportBooleanPropertyAttribute(
829
0
                OAttributeMetaData::getDatabaseAttributeNamespace(),
830
0
                OAttributeMetaData::getDatabaseAttributeName(DAFlags::ConvertEmpty),
831
0
                PROPERTY_EMPTY_IS_NULL,
832
0
                BoolAttrFlags::DefaultFalse
833
0
                );
834
0
            RESET_BIT( nIncludeDatabase, DAFlags::ConvertEmpty );
835
0
        }
836
837
        // the only enum property: ListSourceType
838
0
        if (DAFlags::ListSource_TYPE & m_nIncludeDatabase)
839
0
        {
840
0
            exportEnumPropertyAttribute(
841
0
                OAttributeMetaData::getDatabaseAttributeNamespace(),
842
0
                OAttributeMetaData::getDatabaseAttributeName(DAFlags::ListSource_TYPE),
843
0
                PROPERTY_LISTSOURCETYPE,
844
0
                aListSourceTypeMap,
845
0
                ListSourceType_VALUELIST
846
0
                );
847
0
            RESET_BIT( nIncludeDatabase, DAFlags::ListSource_TYPE );
848
0
        }
849
850
0
        if (m_nIncludeDatabase & DAFlags::ListSource)
851
0
        {
852
0
            exportListSourceAsAttribute();
853
0
            RESET_BIT( nIncludeDatabase, DAFlags::ListSource );
854
0
        }
855
856
#if OSL_DEBUG_LEVEL > 0
857
        OSL_ENSURE(DAFlags::NONE == nIncludeDatabase,
858
            "OControlExport::exportDatabaseAttributes: forgot some flags!");
859
            // in the dbg_util version, we should have removed every bit we handled from the mask, so it should
860
            // be 0 now ...
861
#endif
862
0
    }
863
864
    void OControlExport::exportBindingAttributes()
865
0
    {
866
#if OSL_DEBUG_LEVEL > 0
867
        BAFlags nIncludeBinding = m_nIncludeBindings;
868
#endif
869
870
0
        if ( m_nIncludeBindings & BAFlags::LinkedCell )
871
0
        {
872
0
            exportCellBindingAttributes( bool(m_nIncludeBindings & BAFlags::ListLinkingType) );
873
        #if OSL_DEBUG_LEVEL > 0
874
            //  reset the bit for later checking
875
            nIncludeBinding = nIncludeBinding & ~BAFlags( BAFlags::LinkedCell | BAFlags::ListLinkingType );
876
        #endif
877
0
        }
878
879
0
        if ( m_nIncludeBindings & BAFlags::ListCellRange )
880
0
        {
881
0
            exportCellListSourceRange();
882
        #if OSL_DEBUG_LEVEL > 0
883
            //  reset the bit for later checking
884
            nIncludeBinding = nIncludeBinding & ~BAFlags::ListCellRange;
885
        #endif
886
0
        }
887
888
0
        if ( m_nIncludeBindings & BAFlags::XFormsBind )
889
0
        {
890
0
            exportXFormsBindAttributes();
891
        #if OSL_DEBUG_LEVEL > 0
892
            //  reset the bit for later checking
893
            nIncludeBinding = nIncludeBinding & ~BAFlags::XFormsBind;
894
        #endif
895
0
        }
896
897
0
        if ( m_nIncludeBindings & BAFlags::XFormsListBind )
898
0
        {
899
0
            exportXFormsListAttributes();
900
        #if OSL_DEBUG_LEVEL > 0
901
            //  reset the bit for later checking
902
            nIncludeBinding = nIncludeBinding & ~BAFlags::XFormsListBind;
903
        #endif
904
0
        }
905
906
0
        if ( m_nIncludeBindings & BAFlags::XFormsSubmission )
907
0
        {
908
0
            exportXFormsSubmissionAttributes();
909
        #if OSL_DEBUG_LEVEL > 0
910
            //  reset the bit for later checking
911
            nIncludeBinding = nIncludeBinding & ~BAFlags::XFormsSubmission;
912
        #endif
913
0
        }
914
915
        #if OSL_DEBUG_LEVEL > 0
916
        OSL_ENSURE( BAFlags::NONE == nIncludeBinding,
917
            "OControlExport::exportBindingAttributes: forgot some flags!");
918
            // in the debug version, we should have removed every bit we handled from the mask, so it should
919
            // be 0 now ...
920
        #endif
921
0
    }
922
923
    void OControlExport::exportSpecialAttributes()
924
0
    {
925
0
        sal_Int32 i=0;
926
927
        // the boolean properties
928
0
        {
929
0
            static const SCAFlags nBooleanPropertyAttributeIds[] =
930
0
            {   // attribute flags
931
0
                SCAFlags::Validation, SCAFlags::MultiLine, SCAFlags::AutoCompletion, SCAFlags::Multiple, SCAFlags::DefaultButton, SCAFlags::IsTristate,
932
0
                SCAFlags::Toggle, SCAFlags::FocusOnClick
933
0
            };
934
0
            static constexpr OUString pBooleanPropertyNames[] =
935
0
            {   // property names
936
0
                PROPERTY_STRICTFORMAT, PROPERTY_MULTILINE,
937
0
                PROPERTY_AUTOCOMPLETE,
938
0
                PROPERTY_MULTISELECTION,
939
0
                PROPERTY_DEFAULTBUTTON, PROPERTY_TRISTATE,
940
0
                PROPERTY_TOGGLE, PROPERTY_FOCUS_ON_CLICK
941
0
            };
942
0
            static const sal_Int32 nIdCount = std::size(nBooleanPropertyAttributeIds);
943
        #if OSL_DEBUG_LEVEL > 0
944
            static const sal_Int32 nNameCount = std::size(pBooleanPropertyNames);
945
            OSL_ENSURE((nIdCount == nNameCount),
946
                "OControlExport::exportSpecialAttributes: somebody tampered with the maps (1)!");
947
        #endif
948
0
            const SCAFlags* pAttributeId = nBooleanPropertyAttributeIds;
949
0
            for ( i = 0; i < nIdCount; ++i, ++pAttributeId )
950
0
            {
951
0
                if ( *pAttributeId & m_nIncludeSpecial)
952
0
                {
953
0
                    exportBooleanPropertyAttribute(
954
0
                        OAttributeMetaData::getSpecialAttributeNamespace( *pAttributeId ),
955
0
                        OAttributeMetaData::getSpecialAttributeName( *pAttributeId ),
956
0
                        pBooleanPropertyNames[i],
957
0
                        ( *pAttributeId == SCAFlags::FocusOnClick ) ? BoolAttrFlags::DefaultTrue : BoolAttrFlags::DefaultFalse
958
0
                    );
959
            #if OSL_DEBUG_LEVEL > 0
960
                    //  reset the bit for later checking
961
                    m_nIncludeSpecial = m_nIncludeSpecial & ~*pAttributeId;
962
            #endif
963
0
                }
964
0
            }
965
0
        }
966
967
        // the integer properties
968
0
        {
969
0
            static const SCAFlags nIntegerPropertyAttributeIds[] =
970
0
            {   // attribute flags
971
0
                SCAFlags::PageStepSize
972
0
            };
973
0
            static constexpr OUString pIntegerPropertyNames[] =
974
0
            {   // property names
975
0
                PROPERTY_BLOCK_INCREMENT
976
0
            };
977
0
            static const sal_Int32 nIntegerPropertyAttrDefaults[] =
978
0
            {   // attribute defaults (XML defaults, not runtime defaults!)
979
0
                10
980
0
            };
981
982
0
            static const sal_Int32 nIdCount = std::size( nIntegerPropertyAttributeIds );
983
        #if OSL_DEBUG_LEVEL > 0
984
            static const sal_Int32 nNameCount = std::size( pIntegerPropertyNames );
985
            OSL_ENSURE( ( nIdCount == nNameCount ),
986
                "OControlExport::exportSpecialAttributes: somebody tampered with the maps (2)!" );
987
            static const sal_Int32 nDefaultCount = std::size( nIntegerPropertyAttrDefaults );
988
            OSL_ENSURE( ( nIdCount == nDefaultCount ),
989
                "OControlExport::exportSpecialAttributes: somebody tampered with the maps (3)!" );
990
        #endif
991
0
            for ( i = 0; i < nIdCount; ++i )
992
0
                if ( nIntegerPropertyAttributeIds[i] & m_nIncludeSpecial )
993
0
                {
994
0
                    exportInt32PropertyAttribute(
995
0
                        OAttributeMetaData::getSpecialAttributeNamespace( nIntegerPropertyAttributeIds[i] ),
996
0
                        OAttributeMetaData::getSpecialAttributeName( nIntegerPropertyAttributeIds[i] ),
997
0
                        pIntegerPropertyNames[i],
998
0
                        nIntegerPropertyAttrDefaults[i]
999
0
                    );
1000
            #if OSL_DEBUG_LEVEL > 0
1001
                    //  reset the bit for later checking
1002
                    m_nIncludeSpecial = m_nIncludeSpecial & ~nIntegerPropertyAttributeIds[i];
1003
            #endif
1004
0
                }
1005
1006
0
            if ( SCAFlags::StepSize & m_nIncludeSpecial )
1007
0
            {
1008
0
                OUString sPropertyName;
1009
0
                if ( m_xPropertyInfo->hasPropertyByName( PROPERTY_LINE_INCREMENT ) )
1010
0
                    sPropertyName = PROPERTY_LINE_INCREMENT;
1011
0
                else if ( m_xPropertyInfo->hasPropertyByName( PROPERTY_SPIN_INCREMENT ) )
1012
0
                    sPropertyName = PROPERTY_SPIN_INCREMENT;
1013
0
                else
1014
0
                    OSL_FAIL( "OControlExport::exportSpecialAttributes: not property which can be mapped to step-size attribute!" );
1015
1016
0
                if ( !sPropertyName.isEmpty() )
1017
0
                    exportInt32PropertyAttribute(
1018
0
                        OAttributeMetaData::getSpecialAttributeNamespace( SCAFlags::StepSize ),
1019
0
                        OAttributeMetaData::getSpecialAttributeName( SCAFlags::StepSize ),
1020
0
                        sPropertyName,
1021
0
                        1
1022
0
                    );
1023
1024
            #if OSL_DEBUG_LEVEL > 0
1025
                //  reset the bit for later checking
1026
                m_nIncludeSpecial = m_nIncludeSpecial & ~SCAFlags::StepSize;
1027
            #endif
1028
0
            }
1029
1030
0
        }
1031
1032
        // the enum properties
1033
0
        {
1034
0
            if (SCAFlags::State & m_nIncludeSpecial)
1035
0
            {
1036
0
                exportEnumPropertyAttribute(
1037
0
                    OAttributeMetaData::getSpecialAttributeNamespace(SCAFlags::State),
1038
0
                    OAttributeMetaData::getSpecialAttributeName(SCAFlags::State),
1039
0
                    PROPERTY_DEFAULT_STATE,
1040
0
                    aCheckStateMap,
1041
0
                    TRISTATE_FALSE);
1042
            #if OSL_DEBUG_LEVEL > 0
1043
                //  reset the bit for later checking
1044
                m_nIncludeSpecial = m_nIncludeSpecial & ~SCAFlags::State;
1045
            #endif
1046
0
            }
1047
1048
0
            if (SCAFlags::CurrentState & m_nIncludeSpecial)
1049
0
            {
1050
0
                exportEnumPropertyAttribute(
1051
0
                    OAttributeMetaData::getSpecialAttributeNamespace(SCAFlags::CurrentState),
1052
0
                    OAttributeMetaData::getSpecialAttributeName(SCAFlags::CurrentState),
1053
0
                    PROPERTY_STATE,
1054
0
                    aCheckStateMap,
1055
0
                    TRISTATE_FALSE);
1056
            #if OSL_DEBUG_LEVEL > 0
1057
                //  reset the bit for later checking
1058
                m_nIncludeSpecial = m_nIncludeSpecial & ~SCAFlags::CurrentState;
1059
            #endif
1060
0
            }
1061
0
        }
1062
1063
        // some properties which require a special handling
1064
        // the repeat delay
1065
0
        {
1066
0
            if ( m_nIncludeSpecial & SCAFlags::RepeatDelay )
1067
0
            {
1068
0
                DBG_CHECK_PROPERTY( PROPERTY_REPEAT_DELAY, sal_Int32 );
1069
1070
0
                sal_Int32 nRepeatDelay = 0;
1071
0
                m_xProps->getPropertyValue( PROPERTY_REPEAT_DELAY ) >>= nRepeatDelay;
1072
0
                tools::Time aTime(tools::Time::EMPTY);
1073
0
                aTime.MakeTimeFromMS( nRepeatDelay );
1074
0
                util::Duration aDuration;
1075
0
                aDuration.Hours   = aTime.GetHour();
1076
0
                aDuration.Minutes = aTime.GetMin();
1077
0
                aDuration.Seconds = aTime.GetSec();
1078
0
                aDuration.NanoSeconds = (nRepeatDelay % 1000) * 1000000;
1079
1080
0
                OUStringBuffer buf;
1081
0
                ::sax::Converter::convertDuration(buf, aDuration);
1082
0
                AddAttribute(OAttributeMetaData::getSpecialAttributeNamespace( SCAFlags::RepeatDelay )
1083
0
                            ,OAttributeMetaData::getSpecialAttributeName( SCAFlags::RepeatDelay )
1084
0
                            ,buf.makeStringAndClear());
1085
1086
0
                exportedProperty( PROPERTY_REPEAT_DELAY );
1087
1088
            #if OSL_DEBUG_LEVEL > 0
1089
                //  reset the bit for later checking
1090
                m_nIncludeSpecial = m_nIncludeSpecial & ~SCAFlags::RepeatDelay;
1091
            #endif
1092
0
            }
1093
0
        }
1094
1095
        // the EchoChar property needs special handling, cause it's a Int16, but must be stored as one-character-string
1096
0
        {
1097
0
            if (SCAFlags::EchoChar & m_nIncludeSpecial)
1098
0
            {
1099
0
                DBG_CHECK_PROPERTY( PROPERTY_ECHO_CHAR, sal_Int16 );
1100
0
                sal_Int16 nValue(0);
1101
0
                m_xProps->getPropertyValue(PROPERTY_ECHO_CHAR) >>= nValue;
1102
0
                if (nValue)
1103
0
                {
1104
0
                    OUString sCharacter(reinterpret_cast<const sal_Unicode*>(&nValue), 1);
1105
0
                    AddAttribute(
1106
0
                        OAttributeMetaData::getSpecialAttributeNamespace(SCAFlags::EchoChar),
1107
0
                        OAttributeMetaData::getSpecialAttributeName(SCAFlags::EchoChar),
1108
0
                        sCharacter);
1109
0
                }
1110
0
                exportedProperty(PROPERTY_ECHO_CHAR);
1111
            #if OSL_DEBUG_LEVEL > 0
1112
                //  reset the bit for later checking
1113
                m_nIncludeSpecial = m_nIncludeSpecial & ~SCAFlags::EchoChar;
1114
            #endif
1115
0
            }
1116
0
        }
1117
1118
        // the string properties
1119
0
        {
1120
0
            static const SCAFlags nStringPropertyAttributeIds[] =
1121
0
            {   // attribute flags
1122
0
                SCAFlags::GroupName
1123
0
            };
1124
0
            static constexpr OUString pStringPropertyNames[] =
1125
0
            {   // property names
1126
0
                PROPERTY_GROUP_NAME
1127
0
            };
1128
1129
0
            static const sal_Int32 nIdCount = std::size( nStringPropertyAttributeIds );
1130
        #if OSL_DEBUG_LEVEL > 0
1131
            static const sal_Int32 nNameCount = std::size( pStringPropertyNames );
1132
            OSL_ENSURE( ( nIdCount == nNameCount ),
1133
                "OControlExport::exportSpecialAttributes: somebody tampered with the maps (2)!" );
1134
        #endif
1135
0
            for ( i = 0; i < nIdCount; ++i )
1136
0
                if ( nStringPropertyAttributeIds[i] & m_nIncludeSpecial )
1137
0
                {
1138
0
                    exportStringPropertyAttribute(
1139
0
                        OAttributeMetaData::getSpecialAttributeNamespace( nStringPropertyAttributeIds[i] ),
1140
0
                        OAttributeMetaData::getSpecialAttributeName( nStringPropertyAttributeIds[i] ),
1141
0
                        pStringPropertyNames[i]
1142
0
                    );
1143
            #if OSL_DEBUG_LEVEL > 0
1144
                    //  reset the bit for later checking
1145
                    m_nIncludeSpecial = m_nIncludeSpecial & ~nStringPropertyAttributeIds[i];
1146
            #endif
1147
0
                }
1148
0
        }
1149
1150
0
        if ((SCAFlags::MinValue | SCAFlags::MaxValue) & m_nIncludeSpecial)
1151
0
        {
1152
            // need to export the min value and the max value as attributes
1153
            // It depends on the real type (FormComponentType) of the control, which properties hold these
1154
            // values
1155
0
            OUString pMinValuePropertyName;
1156
0
            OUString pMaxValuePropertyName;
1157
0
            getValueLimitPropertyNames(m_nClassId, pMinValuePropertyName, pMaxValuePropertyName);
1158
1159
0
            OSL_ENSURE((pMinValuePropertyName.isEmpty()) == (SCAFlags::NONE == (SCAFlags::MinValue & m_nIncludeSpecial)),
1160
0
                "OControlExport::exportCommonControlAttributes: no property found for the min value attribute!");
1161
0
            OSL_ENSURE((pMaxValuePropertyName.isEmpty()) == (SCAFlags::NONE == (SCAFlags::MaxValue & m_nIncludeSpecial)),
1162
0
                "OControlExport::exportCommonControlAttributes: no property found for the max value attribute!");
1163
1164
            // add the two attributes
1165
0
            static const OUString pMinValueAttributeName = OAttributeMetaData::getSpecialAttributeName(SCAFlags::MinValue);
1166
0
            static const OUString pMaxValueAttributeName = OAttributeMetaData::getSpecialAttributeName(SCAFlags::MaxValue);
1167
0
            static const sal_uInt16 nMinValueNamespaceKey = OAttributeMetaData::getSpecialAttributeNamespace(SCAFlags::MinValue);
1168
0
            static const sal_uInt16 nMaxValueNamespaceKey = OAttributeMetaData::getSpecialAttributeNamespace(SCAFlags::MaxValue);
1169
1170
0
            if (!pMinValuePropertyName.isEmpty() && (SCAFlags::MinValue & m_nIncludeSpecial))
1171
0
                exportGenericPropertyAttribute(
1172
0
                    nMinValueNamespaceKey,
1173
0
                    pMinValueAttributeName,
1174
0
                    pMinValuePropertyName);
1175
1176
0
            if (!pMaxValuePropertyName.isEmpty() && (SCAFlags::MaxValue & m_nIncludeSpecial))
1177
0
                exportGenericPropertyAttribute(
1178
0
                    nMaxValueNamespaceKey,
1179
0
                    pMaxValueAttributeName,
1180
0
                    pMaxValuePropertyName);
1181
        #if OSL_DEBUG_LEVEL > 0
1182
            //  reset the bit for later checking
1183
            m_nIncludeSpecial = m_nIncludeSpecial & ~SCAFlags(SCAFlags::MinValue | SCAFlags::MaxValue);
1184
        #endif
1185
0
        }
1186
1187
0
        if ( SCAFlags::ImagePosition & m_nIncludeSpecial )
1188
0
        {
1189
0
            exportImagePositionAttributes();
1190
0
            RESET_BIT( m_nIncludeSpecial, SCAFlags::ImagePosition );
1191
0
        }
1192
1193
0
        OSL_ENSURE(SCAFlags::NONE == m_nIncludeSpecial,
1194
0
            "OControlExport::exportSpecialAttributes: forgot some flags!");
1195
            // in the dbg_util version, we should have removed every bit we handled from the mask, so it should
1196
            // be 0 now ...
1197
0
    }
1198
1199
    OUString OControlExport::getScalarListSourceValue() const
1200
0
    {
1201
0
        OUString sListSource;
1202
0
        Any aListSource = m_xProps->getPropertyValue( PROPERTY_LISTSOURCE );
1203
0
        if ( !( aListSource >>= sListSource ) )
1204
0
        {
1205
0
            Sequence< OUString > aListSourceSequence;
1206
0
            aListSource >>= aListSourceSequence;
1207
0
            if ( aListSourceSequence.hasElements() )
1208
0
                sListSource = aListSourceSequence[ 0 ];
1209
0
        }
1210
0
        return sListSource;
1211
0
    }
1212
1213
    void OControlExport::exportListSourceAsAttribute()
1214
0
    {
1215
        // DAFlags::ListSource needs some special handling
1216
0
        DBG_CHECK_PROPERTY_NO_TYPE( PROPERTY_LISTSOURCE );
1217
1218
0
        OUString sListSource = getScalarListSourceValue();
1219
0
        if ( !sListSource.isEmpty() )
1220
0
        {   // the ListSource property needs to be exported as attribute, and it is not empty
1221
0
            AddAttribute(
1222
0
                OAttributeMetaData::getDatabaseAttributeNamespace(),
1223
0
                OAttributeMetaData::getDatabaseAttributeName(DAFlags::ListSource),
1224
0
                sListSource);
1225
0
        }
1226
1227
0
        exportedProperty( PROPERTY_LISTSOURCE );
1228
0
    }
1229
1230
    void OControlExport::getSequenceInt16PropertyAsSet(const OUString& _rPropertyName, Int16Set& _rOut)
1231
0
    {
1232
0
        Sequence< sal_Int16 > aValueSequence;
1233
0
        DBG_CHECK_PROPERTY(_rPropertyName, Sequence< sal_Int16 >);
1234
0
        m_xProps->getPropertyValue(_rPropertyName) >>= aValueSequence;
1235
1236
0
        for (const auto& rValue : aValueSequence)
1237
0
            _rOut.insert(rValue);
1238
0
    }
1239
1240
    void OControlExport::exportListSourceAsElements()
1241
0
    {
1242
        // the string lists
1243
0
        Sequence< OUString > aItems, aValues;
1244
0
        DBG_CHECK_PROPERTY( PROPERTY_STRING_ITEM_LIST, Sequence< OUString > );
1245
0
        m_xProps->getPropertyValue(PROPERTY_STRING_ITEM_LIST) >>= aItems;
1246
1247
0
        DBG_CHECK_PROPERTY( PROPERTY_LISTSOURCE, Sequence< OUString > );
1248
0
        if ( DAFlags::NONE == ( m_nIncludeDatabase & DAFlags::ListSource ) )
1249
0
            m_xProps->getPropertyValue(PROPERTY_LISTSOURCE) >>= aValues;
1250
        // if we exported the list source as attribute, we do not repeat it as sub elements
1251
1252
        // the selection lists
1253
0
        Int16Set aSelection, aDefaultSelection;
1254
0
        getSequenceInt16PropertyAsSet(PROPERTY_SELECT_SEQ, aSelection);
1255
0
        getSequenceInt16PropertyAsSet(PROPERTY_DEFAULT_SELECT_SEQ, aDefaultSelection);
1256
1257
        // the string for "true"
1258
0
        OUString sTrue;
1259
0
        OUStringBuffer sBuffer;
1260
0
        ::sax::Converter::convertBool(sBuffer, true);
1261
0
        sTrue = sBuffer.makeStringAndClear();
1262
1263
        // loop through both lists ('til the maximum of both lengths)
1264
0
        const OUString* pItems = aItems.getConstArray();
1265
0
        const OUString* pValues = aValues.getConstArray();
1266
1267
0
        sal_Int32 nItems = aItems.getLength();
1268
0
        sal_Int32 nValues = aValues.getLength();
1269
1270
0
        sal_Int16 nMaxLen = static_cast<sal_Int16>(std::max(nItems, nValues));
1271
1272
0
        for (sal_Int16 i=0; i<nMaxLen; ++i )
1273
0
        {
1274
0
            m_rContext.getGlobalContext().ClearAttrList();
1275
0
            if (i < nItems)
1276
0
            {
1277
                // there is an item at this position
1278
0
                AddAttribute(
1279
0
                    OAttributeMetaData::getCommonControlAttributeNamespace(CCAFlags::Label),
1280
0
                    OAttributeMetaData::getCommonControlAttributeName(CCAFlags::Label),
1281
0
                    *pItems);
1282
0
                ++pItems;
1283
0
            }
1284
0
            if (i < nValues)
1285
0
            {
1286
                // there is a value at this position
1287
0
                AddAttribute(
1288
0
                    OAttributeMetaData::getCommonControlAttributeNamespace(CCAFlags::Value),
1289
0
                    OAttributeMetaData::getCommonControlAttributeName(CCAFlags::Value),
1290
0
                    *pValues);
1291
0
                ++pValues;
1292
0
            }
1293
1294
0
            Int16Set::const_iterator aSelectedPos = aSelection.find(i);
1295
0
            if (aSelection.end() != aSelectedPos)
1296
0
            {   // the item at this position is selected
1297
0
                AddAttribute(
1298
0
                    OAttributeMetaData::getCommonControlAttributeNamespace(CCAFlags::CurrentSelected),
1299
0
                    OAttributeMetaData::getCommonControlAttributeName(CCAFlags::CurrentSelected),
1300
0
                    sTrue
1301
0
                    );
1302
0
                aSelection.erase(aSelectedPos);
1303
0
            }
1304
1305
0
            Int16Set::const_iterator aDefaultSelectedPos = aDefaultSelection.find(i);
1306
0
            if (aDefaultSelection.end() != aDefaultSelectedPos)
1307
0
            {   // the item at this position is selected as default
1308
0
                AddAttribute(
1309
0
                    OAttributeMetaData::getCommonControlAttributeNamespace(CCAFlags::Selected),
1310
0
                    OAttributeMetaData::getCommonControlAttributeName(CCAFlags::Selected),
1311
0
                    sTrue
1312
0
                    );
1313
0
                aDefaultSelection.erase(aDefaultSelectedPos);
1314
0
            }
1315
0
            SvXMLElementExport aFormElement(m_rContext.getGlobalContext(), XML_NAMESPACE_FORM, u"option"_ustr, true, true);
1316
0
        }
1317
1318
        // There may be more "selected" or "default-selected" items than there are in the lists in real,
1319
        // so we need to store some additional "form:option" items which have no name and no label, but
1320
        // one or both of the selected flags.
1321
        // 21.05.2001 - 85388 - frank.schoenheit@germany.sun.com
1322
1323
0
        if (aSelection.empty() && aDefaultSelection.empty())
1324
0
            return;
1325
1326
0
        sal_Int16 nLastSelected = -1;
1327
0
        if ( !aSelection.empty() )
1328
0
            nLastSelected = *(--aSelection.end());
1329
1330
0
        sal_Int16 nLastDefaultSelected = -1;
1331
0
        if ( !aDefaultSelection.empty() )
1332
0
            nLastDefaultSelected = *(--aDefaultSelection.end());
1333
1334
        // the maximum element in both sets
1335
0
        sal_Int16 nLastReferredEntry = std::max(nLastSelected, nLastDefaultSelected);
1336
0
        OSL_ENSURE(nLastReferredEntry >= nMaxLen, "OControlExport::exportListSourceAsElements: inconsistence!");
1337
            // if the maximum (selected or default selected) entry number is less than the maximum item count
1338
            // in both lists, the entry number should have been removed from the set
1339
1340
0
        for (sal_Int16 i=nMaxLen; i<=nLastReferredEntry; ++i)
1341
0
        {
1342
0
            if (aSelection.end() != aSelection.find(i))
1343
0
            {   // the (not existent) item at this position is selected
1344
0
                AddAttribute(
1345
0
                    OAttributeMetaData::getCommonControlAttributeNamespace(CCAFlags::CurrentSelected),
1346
0
                    OAttributeMetaData::getCommonControlAttributeName(CCAFlags::CurrentSelected),
1347
0
                    sTrue
1348
0
                    );
1349
0
            }
1350
1351
0
            if (aDefaultSelection.end() != aDefaultSelection.find(i))
1352
0
            {   // the (not existent) item at this position is selected as default
1353
0
                AddAttribute(
1354
0
                    OAttributeMetaData::getCommonControlAttributeNamespace(CCAFlags::Selected),
1355
0
                    OAttributeMetaData::getCommonControlAttributeName(CCAFlags::Selected),
1356
0
                    sTrue
1357
0
                    );
1358
0
            }
1359
0
            SvXMLElementExport aFormElement(m_rContext.getGlobalContext(), XML_NAMESPACE_FORM, u"option"_ustr, true, true);
1360
0
        }
1361
0
    }
1362
1363
    void OControlExport::implStartElement(const OUString& _pName)
1364
0
    {
1365
        // before we let the base class start it's outer element, we add a wrapper element
1366
0
        OUString pOuterElementName = getOuterXMLElementName();
1367
0
        if (!pOuterElementName.isEmpty())
1368
0
            m_pOuterElement = std::make_unique<SvXMLElementExport>(
1369
0
                                        m_rContext.getGlobalContext(),
1370
0
                                        XML_NAMESPACE_FORM,
1371
0
                                        pOuterElementName, true,
1372
0
                                        true);
1373
1374
        // add the attributes for the inner element
1375
0
        exportInnerAttributes();
1376
1377
        // and start the inner element
1378
0
        OElementExport::implStartElement(_pName);
1379
0
    }
1380
1381
    void OControlExport::implEndElement()
1382
0
    {
1383
        // end the inner element
1384
0
        OElementExport::implEndElement();
1385
1386
        // end the outer element if it exists
1387
0
        m_pOuterElement.reset();
1388
0
    }
1389
1390
    OUString OControlExport::getOuterXMLElementName() const
1391
0
    {
1392
0
        return u""_ustr;
1393
0
    }
1394
1395
    OUString OControlExport::getXMLElementName() const
1396
0
    {
1397
0
        return getElementName(m_eType);
1398
0
    }
1399
1400
    void OControlExport::examine()
1401
0
    {
1402
0
        OSL_ENSURE( ( m_nIncludeCommon == CCAFlags::NONE ) && ( m_nIncludeSpecial == SCAFlags::NONE ) && ( m_nIncludeDatabase == DAFlags::NONE )
1403
0
                 && ( m_nIncludeEvents == EAFlags::NONE ) && ( m_nIncludeBindings == BAFlags::NONE),
1404
0
                 "OControlExport::examine: called me twice? Not initialized?" );
1405
1406
        // get the class id to decide which kind of element we need in the XML stream
1407
0
        m_nClassId = FormComponentType::CONTROL;
1408
0
        DBG_CHECK_PROPERTY( PROPERTY_CLASSID, sal_Int16 );
1409
0
        m_xProps->getPropertyValue(PROPERTY_CLASSID) >>= m_nClassId;
1410
0
        bool knownType = false;
1411
0
        switch (m_nClassId)
1412
0
        {
1413
0
            case FormComponentType::DATEFIELD:
1414
0
                m_eType = DATE;
1415
0
                knownType = true;
1416
0
                [[fallthrough]];
1417
0
            case FormComponentType::TIMEFIELD:
1418
0
                if ( !knownType )
1419
0
                {
1420
0
                    m_eType = TIME;
1421
0
                    knownType = true;
1422
0
                }
1423
0
                m_nIncludeSpecial |= SCAFlags::Validation;
1424
0
                [[fallthrough]];
1425
0
            case FormComponentType::NUMERICFIELD:
1426
0
            case FormComponentType::CURRENCYFIELD:
1427
0
            case FormComponentType::PATTERNFIELD:
1428
0
                if ( !knownType )
1429
0
                {
1430
0
                    m_eType = FORMATTED_TEXT;
1431
0
                    knownType = true;
1432
0
                }
1433
0
                [[fallthrough]];
1434
0
            case FormComponentType::TEXTFIELD:
1435
0
            {   // it's some kind of edit. To know which type we need further investigation
1436
1437
0
                if ( !knownType )
1438
0
                {
1439
                    // check if it's a formatted field
1440
0
                    if (m_xPropertyInfo->hasPropertyByName(PROPERTY_FORMATKEY))
1441
0
                    {
1442
0
                        m_eType = FORMATTED_TEXT;
1443
0
                    }
1444
0
                    else
1445
0
                    {
1446
                        // all other controls are represented by an ordinary edit control, but which XML control type
1447
                        // it is depends on the current values of some properties
1448
1449
                        // if the EchoChar string is not empty, it is a password field
1450
0
                        sal_Int16 nEchoChar = 0;
1451
0
                        if (m_xPropertyInfo->hasPropertyByName(PROPERTY_ECHOCHAR))
1452
                            // grid columns do not have this property...
1453
0
                            m_xProps->getPropertyValue(PROPERTY_ECHOCHAR) >>= nEchoChar;
1454
0
                        if (nEchoChar)
1455
0
                        {
1456
0
                            m_eType = PASSWORD;
1457
0
                            m_nIncludeSpecial |= SCAFlags::EchoChar;
1458
0
                        }
1459
0
                        else
1460
0
                        {
1461
                            // if the MultiLine property is sal_True, it is a TextArea
1462
0
                            bool bMultiLine = false;
1463
0
                            if (m_xPropertyInfo->hasPropertyByName(PROPERTY_MULTILINE))
1464
                                // grid columns do not have this property...
1465
0
                                bMultiLine = ::cppu::any2bool(m_xProps->getPropertyValue(PROPERTY_MULTILINE));
1466
1467
0
                            if ( bMultiLine )
1468
0
                                m_eType = TEXT_AREA;
1469
0
                            else
1470
                                // the only case left is represented by a Text element
1471
0
                                m_eType = TEXT;
1472
0
                        }
1473
0
                    }
1474
0
                }
1475
1476
                // attributes which are common to all the types:
1477
                // common attributes
1478
0
                m_nIncludeCommon =
1479
0
                    CCAFlags::Name | CCAFlags::ServiceName | CCAFlags::Disabled |
1480
0
                    CCAFlags::Printable | CCAFlags::TabIndex | CCAFlags::TabStop | CCAFlags::Title;
1481
1482
0
                if  (   ( m_nClassId != FormComponentType::DATEFIELD )
1483
0
                    &&  ( m_nClassId != FormComponentType::TIMEFIELD )
1484
0
                    )
1485
                    // date and time field values are handled differently nowadays
1486
0
                    m_nIncludeCommon |= CCAFlags::Value;
1487
1488
                // database attributes
1489
0
                m_nIncludeDatabase = DAFlags::DataField | DAFlags::InputRequired;
1490
1491
                // event attributes
1492
0
                m_nIncludeEvents = EAFlags::ControlEvents | EAFlags::OnChange | EAFlags::OnSelect;
1493
1494
                // only text and pattern fields have a ConvertEmptyToNull property
1495
0
                if  (   ( m_nClassId == FormComponentType::TEXTFIELD )
1496
0
                    ||  ( m_nClassId == FormComponentType::PATTERNFIELD )
1497
0
                    )
1498
0
                    m_nIncludeDatabase |= DAFlags::ConvertEmpty;
1499
1500
                // all controls but the file control fields have a readonly property
1501
0
                if ( m_nClassId != FormComponentType::FILECONTROL )
1502
0
                    m_nIncludeCommon |= CCAFlags::ReadOnly;
1503
1504
                // a text field has a max text len
1505
0
                if ( m_nClassId == FormComponentType::TEXTFIELD )
1506
0
                    m_nIncludeCommon |= CCAFlags::MaxLength;
1507
1508
                // max and min values and validation:
1509
0
                if (FORMATTED_TEXT == m_eType)
1510
0
                {   // in general all controls represented as formatted-text have these props
1511
0
                    if  ( FormComponentType::PATTERNFIELD != m_nClassId )   // except the PatternField
1512
0
                        m_nIncludeSpecial |= SCAFlags::MaxValue | SCAFlags::MinValue;
1513
1514
0
                    if (FormComponentType::TEXTFIELD != m_nClassId)
1515
                        // and the FormattedField does not have a validation flag
1516
0
                        m_nIncludeSpecial |= SCAFlags::Validation;
1517
0
                }
1518
1519
                // if it's not a password field or rich text control, the CurrentValue needs to be stored, too
1520
0
                if  (   ( PASSWORD != m_eType )
1521
0
                    &&  ( DATE != m_eType )
1522
0
                    &&  ( TIME != m_eType )
1523
0
                    )
1524
0
                {
1525
0
                    m_nIncludeCommon |= CCAFlags::CurrentValue;
1526
0
                }
1527
0
            }
1528
0
            break;
1529
1530
0
            case FormComponentType::FILECONTROL:
1531
0
                m_eType = FILE;
1532
0
                m_nIncludeCommon =
1533
0
                    CCAFlags::Name | CCAFlags::ServiceName | CCAFlags::CurrentValue | CCAFlags::Disabled |
1534
0
                    CCAFlags::Printable | CCAFlags::TabIndex | CCAFlags::TabStop | CCAFlags::Title |
1535
0
                    CCAFlags::Value;
1536
0
                m_nIncludeEvents = EAFlags::ControlEvents | EAFlags::OnChange | EAFlags::OnSelect;
1537
0
                break;
1538
1539
0
            case FormComponentType::FIXEDTEXT:
1540
0
                m_eType = FIXED_TEXT;
1541
0
                m_nIncludeCommon =
1542
0
                    CCAFlags::Name | CCAFlags::ServiceName | CCAFlags::Disabled | CCAFlags::Label |
1543
0
                    CCAFlags::Printable | CCAFlags::Title | CCAFlags::For;
1544
0
                m_nIncludeSpecial = SCAFlags::MultiLine;
1545
0
                m_nIncludeEvents = EAFlags::ControlEvents;
1546
0
                break;
1547
1548
0
            case FormComponentType::COMBOBOX:
1549
0
                m_eType = COMBOBOX;
1550
0
                m_nIncludeCommon =
1551
0
                    CCAFlags::Name | CCAFlags::ServiceName | CCAFlags::CurrentValue |
1552
0
                    CCAFlags::Disabled | CCAFlags::Dropdown | CCAFlags::MaxLength | CCAFlags::Printable | CCAFlags::ReadOnly | CCAFlags::Size |
1553
0
                    CCAFlags::TabIndex | CCAFlags::TabStop | CCAFlags::Title | CCAFlags::Value;
1554
0
                m_nIncludeSpecial = SCAFlags::AutoCompletion;
1555
0
                m_nIncludeDatabase = DAFlags::ConvertEmpty | DAFlags::DataField | DAFlags::InputRequired | DAFlags::ListSource | DAFlags::ListSource_TYPE;
1556
0
                m_nIncludeEvents = EAFlags::ControlEvents | EAFlags::OnChange | EAFlags::OnSelect;
1557
0
                break;
1558
1559
0
            case FormComponentType::LISTBOX:
1560
0
                m_eType = LISTBOX;
1561
0
                m_nIncludeCommon =
1562
0
                    CCAFlags::Name | CCAFlags::ServiceName | CCAFlags::Disabled | CCAFlags::Dropdown |
1563
0
                    CCAFlags::Printable | CCAFlags::Size | CCAFlags::TabIndex | CCAFlags::TabStop | CCAFlags::Title;
1564
0
                m_nIncludeSpecial = SCAFlags::Multiple;
1565
0
                m_nIncludeDatabase = DAFlags::BoundColumn | DAFlags::DataField | DAFlags::InputRequired | DAFlags::ListSource_TYPE;
1566
0
                m_nIncludeEvents = EAFlags::ControlEvents | EAFlags::OnChange | EAFlags::OnClick | EAFlags::OnDoubleClick;
1567
                // check if we need to export the ListSource as attribute
1568
0
                {
1569
                    // for a list box, if the ListSourceType is VALUE_LIST, no ListSource is stored, but instead
1570
                    // a sequence of pairs which is built from the StringItemList and the ValueList
1571
0
                    ListSourceType eListSourceType = ListSourceType_VALUELIST;
1572
0
                    bool bSuccess =
1573
0
                        m_xProps->getPropertyValue(PROPERTY_LISTSOURCETYPE) >>= eListSourceType;
1574
0
                    OSL_ENSURE(bSuccess, "OControlExport::examineControl: could not retrieve the ListSourceType!");
1575
0
                    if (ListSourceType_VALUELIST != eListSourceType)
1576
0
                    {
1577
0
                        m_nIncludeDatabase |= DAFlags::ListSource;
1578
0
                    }
1579
0
                }
1580
1581
0
                break;
1582
1583
0
            case FormComponentType::COMMANDBUTTON:
1584
0
                m_eType = BUTTON;
1585
0
                m_nIncludeCommon |= CCAFlags::TabStop | CCAFlags::Label;
1586
0
                m_nIncludeSpecial = SCAFlags::DefaultButton | SCAFlags::Toggle | SCAFlags::FocusOnClick | SCAFlags::ImagePosition | SCAFlags::RepeatDelay;
1587
0
                [[fallthrough]];
1588
0
            case FormComponentType::IMAGEBUTTON:
1589
0
                if (BUTTON != m_eType)
1590
0
                {
1591
                    // not coming from the previous case
1592
0
                    m_eType = IMAGE;
1593
0
                }
1594
0
                m_nIncludeCommon |=
1595
0
                    CCAFlags::Name | CCAFlags::ServiceName | CCAFlags::ButtonType | CCAFlags::Disabled |
1596
0
                    CCAFlags::ImageData | CCAFlags::Printable | CCAFlags::TabIndex | CCAFlags::TargetFrame |
1597
0
                    CCAFlags::TargetLocation | CCAFlags::Title;
1598
0
                m_nIncludeEvents = EAFlags::ControlEvents | EAFlags::OnClick  | EAFlags::OnDoubleClick;
1599
0
                break;
1600
1601
0
            case FormComponentType::CHECKBOX:
1602
0
                m_eType = CHECKBOX;
1603
0
                m_nIncludeSpecial = SCAFlags::CurrentState | SCAFlags::IsTristate | SCAFlags::State;
1604
0
                [[fallthrough]];
1605
0
            case FormComponentType::RADIOBUTTON:
1606
0
                m_nIncludeCommon =
1607
0
                    CCAFlags::Name | CCAFlags::ServiceName | CCAFlags::Disabled | CCAFlags::Label | CCAFlags::Printable |
1608
0
                    CCAFlags::TabIndex | CCAFlags::TabStop | CCAFlags::Title | CCAFlags::Value | CCAFlags::VisualEffect;
1609
0
                if (CHECKBOX != m_eType)
1610
0
                {   // not coming from the previous case
1611
0
                    m_eType = RADIO;
1612
0
                    m_nIncludeCommon |= CCAFlags::CurrentSelected | CCAFlags::Selected;
1613
0
                }
1614
0
                if ( m_xPropertyInfo->hasPropertyByName( PROPERTY_IMAGE_POSITION ) )
1615
0
                    m_nIncludeSpecial |= SCAFlags::ImagePosition;
1616
0
                if ( m_xPropertyInfo->hasPropertyByName( PROPERTY_GROUP_NAME ) )
1617
0
                    m_nIncludeSpecial |= SCAFlags::GroupName;
1618
0
                m_nIncludeDatabase = DAFlags::DataField | DAFlags::InputRequired;
1619
0
                m_nIncludeEvents = EAFlags::ControlEvents | EAFlags::OnChange;
1620
0
                break;
1621
1622
0
            case FormComponentType::GROUPBOX:
1623
0
                m_eType = FRAME;
1624
0
                m_nIncludeCommon =
1625
0
                    CCAFlags::Name | CCAFlags::ServiceName | CCAFlags::Disabled | CCAFlags::Label |
1626
0
                    CCAFlags::Printable | CCAFlags::Title | CCAFlags::For;
1627
0
                m_nIncludeEvents = EAFlags::ControlEvents;
1628
0
                break;
1629
1630
0
            case FormComponentType::IMAGECONTROL:
1631
0
                m_eType = IMAGE_FRAME;
1632
0
                m_nIncludeCommon =
1633
0
                    CCAFlags::Name | CCAFlags::ServiceName | CCAFlags::Disabled | CCAFlags::ImageData |
1634
0
                    CCAFlags::Printable | CCAFlags::ReadOnly | CCAFlags::Title;
1635
0
                m_nIncludeDatabase = DAFlags::DataField | DAFlags::InputRequired;
1636
0
                m_nIncludeEvents = EAFlags::ControlEvents;
1637
0
                break;
1638
1639
0
            case FormComponentType::HIDDENCONTROL:
1640
0
                m_eType = HIDDEN;
1641
0
                m_nIncludeCommon =
1642
0
                    CCAFlags::Name | CCAFlags::ServiceName | CCAFlags::Value;
1643
0
                break;
1644
1645
0
            case FormComponentType::GRIDCONTROL:
1646
0
                m_eType = GRID;
1647
0
                m_nIncludeCommon =
1648
0
                    CCAFlags::Name | CCAFlags::ServiceName | CCAFlags::Disabled | CCAFlags::Printable |
1649
0
                    CCAFlags::TabIndex | CCAFlags::TabStop | CCAFlags::Title;
1650
0
                m_nIncludeEvents = EAFlags::ControlEvents;
1651
0
                break;
1652
1653
0
            case FormComponentType::SCROLLBAR:
1654
0
            case FormComponentType::SPINBUTTON:
1655
0
                m_eType = VALUERANGE;
1656
0
                m_nIncludeCommon =
1657
0
                    CCAFlags::Name | CCAFlags::ServiceName | CCAFlags::Disabled | CCAFlags::Printable |
1658
0
                    CCAFlags::Title | CCAFlags::CurrentValue | CCAFlags::Value | CCAFlags::Orientation;
1659
0
                m_nIncludeSpecial = SCAFlags::MaxValue | SCAFlags::StepSize | SCAFlags::MinValue | SCAFlags::RepeatDelay;
1660
1661
0
                if ( m_nClassId == FormComponentType::SCROLLBAR )
1662
0
                    m_nIncludeSpecial |= SCAFlags::PageStepSize ;
1663
1664
0
                m_nIncludeEvents = EAFlags::ControlEvents;
1665
0
                break;
1666
1667
0
            default:
1668
0
                OSL_FAIL("OControlExport::examineControl: unknown control type (class id)!");
1669
0
                [[fallthrough]];
1670
1671
0
            case FormComponentType::NAVIGATIONBAR:
1672
                // TODO: should we have an own file format for this?
1673
                // NO break
1674
1675
0
            case FormComponentType::CONTROL:
1676
0
                m_eType = GENERIC_CONTROL;
1677
                // unknown control type
1678
0
                m_nIncludeCommon = CCAFlags::Name | CCAFlags::ServiceName;
1679
                    // at least a name should be there, 'cause without a name the control could never have been
1680
                    // inserted into its parent container
1681
                    // In addition, the service name is absolutely necessary to create the control upon reading.
1682
0
                m_nIncludeEvents = EAFlags::ControlEvents;
1683
                    // we always should be able to export events - this is not control type dependent
1684
0
                break;
1685
0
        }
1686
1687
        // in general, all control types need to export the control id
1688
0
        m_nIncludeCommon |= CCAFlags::ControlId;
1689
1690
        // is it a control bound to a calc cell?
1691
0
        if ( FormCellBindingHelper::livesInSpreadsheetDocument( m_xProps ) )
1692
0
        {
1693
0
            FormCellBindingHelper aHelper( m_xProps, nullptr );
1694
1695
0
            if ( FormCellBindingHelper::isCellBinding( aHelper.getCurrentBinding( ) ) )
1696
0
            {
1697
0
                m_nIncludeBindings |= BAFlags::LinkedCell;
1698
0
                if ( m_nClassId == FormComponentType::LISTBOX )
1699
0
                    m_nIncludeBindings |= BAFlags::ListLinkingType;
1700
0
            }
1701
1702
            // is it a list-like control which uses a calc cell range as list source?
1703
0
            if ( FormCellBindingHelper::isCellRangeListSource( aHelper.getCurrentListSource( ) ) )
1704
0
                m_nIncludeBindings |= BAFlags::ListCellRange;
1705
0
        }
1706
1707
        // is control bound to XForms?
1708
0
        if( !getXFormsBindName( m_xProps ).isEmpty() )
1709
0
        {
1710
0
            m_nIncludeBindings |= BAFlags::XFormsBind;
1711
0
        }
1712
1713
        // is (list-)control bound to XForms list?
1714
0
        if( !getXFormsListBindName( m_xProps ).isEmpty() )
1715
0
        {
1716
0
            m_nIncludeBindings |= BAFlags::XFormsListBind;
1717
0
        }
1718
1719
        // does the control have an XForms submission?
1720
0
        if( !getXFormsSubmissionName( m_xProps ).isEmpty() )
1721
0
        {
1722
0
            m_nIncludeBindings |= BAFlags::XFormsSubmission;
1723
0
        }
1724
0
    }
1725
1726
    void OControlExport::exportCellBindingAttributes( bool _bIncludeListLinkageType )
1727
0
    {
1728
0
        try
1729
0
        {
1730
0
            FormCellBindingHelper aHelper( m_xProps, nullptr );
1731
0
            Reference< XValueBinding > xBinding( aHelper.getCurrentBinding() );
1732
0
            OSL_ENSURE( xBinding.is(), "OControlExport::exportCellBindingAttributes: invalid bindable or invalid binding!" );
1733
0
            if ( xBinding.is() )
1734
0
            {
1735
0
                AddAttribute(
1736
0
                    OAttributeMetaData::getBindingAttributeNamespace(),
1737
0
                    OAttributeMetaData::getBindingAttributeName( BAFlags::LinkedCell ),
1738
0
                    aHelper.getStringAddressFromCellBinding( xBinding )
1739
0
                );
1740
1741
0
                if ( _bIncludeListLinkageType )
1742
0
                {
1743
0
                    sal_Int16 nLinkageType = FormCellBindingHelper::isCellIntegerBinding( xBinding ) ? 1 : 0;
1744
1745
0
                    OUStringBuffer sBuffer;
1746
0
                    SvXMLUnitConverter::convertEnum(
1747
0
                        sBuffer,
1748
0
                        nLinkageType,
1749
0
                        aListLinkageMap
1750
0
                    );
1751
1752
0
                    AddAttribute(
1753
0
                        OAttributeMetaData::getBindingAttributeNamespace(),
1754
0
                        OAttributeMetaData::getBindingAttributeName( BAFlags::ListLinkingType ),
1755
0
                        sBuffer.makeStringAndClear()
1756
0
                    );
1757
0
                }
1758
1759
0
            }
1760
0
        }
1761
0
        catch( const Exception& )
1762
0
        {
1763
0
            TOOLS_WARN_EXCEPTION( "xmloff.forms", "OControlExport::exportCellBindingAttributes" );
1764
0
        }
1765
0
    }
1766
1767
    void OControlExport::exportXFormsBindAttributes()
1768
0
    {
1769
0
        OUString sBindName = getXFormsBindName( m_xProps );
1770
0
        AddAttribute( XML_NAMESPACE_XFORMS, XML_BIND, sBindName );
1771
0
    }
1772
    void OControlExport::exportXFormsListAttributes()
1773
0
    {
1774
0
        OUString sBindName = getXFormsListBindName( m_xProps );
1775
0
        AddAttribute( XML_NAMESPACE_FORM, XML_XFORMS_LIST_SOURCE, sBindName );
1776
0
    }
1777
    void OControlExport::exportXFormsSubmissionAttributes()
1778
0
    {
1779
0
        OUString sSubmission = getXFormsSubmissionName( m_xProps );
1780
0
        AddAttribute( XML_NAMESPACE_FORM, XML_XFORMS_SUBMISSION, sSubmission );
1781
0
    }
1782
    void OControlExport::exportCellListSourceRange( )
1783
0
    {
1784
0
        try
1785
0
        {
1786
0
            Reference< XListEntrySink > xSink( m_xProps, UNO_QUERY );
1787
0
            Reference< XListEntrySource > xSource;
1788
0
            if ( xSink.is() )
1789
0
                xSource = xSink->getListEntrySource();
1790
0
            OSL_ENSURE( xSource.is(), "OControlExport::exportCellListSourceRange: list source or sink!" );
1791
0
            if ( xSource.is() )
1792
0
            {
1793
0
                FormCellBindingHelper aHelper( m_xProps, nullptr );
1794
1795
0
                AddAttribute(
1796
0
                    OAttributeMetaData::getBindingAttributeNamespace(),
1797
0
                    OAttributeMetaData::getBindingAttributeName( BAFlags::ListCellRange ),
1798
0
                    aHelper.getStringAddressFromCellListSource( xSource )
1799
0
                );
1800
0
            }
1801
0
        }
1802
0
        catch( const Exception& )
1803
0
        {
1804
0
            TOOLS_WARN_EXCEPTION( "xmloff.forms", "OControlExport::exportCellListSourceRange" );
1805
0
        }
1806
0
    }
1807
1808
    void OControlExport::exportImagePositionAttributes()
1809
0
    {
1810
0
        try
1811
0
        {
1812
0
            sal_Int16 nImagePosition = ImagePosition::Centered;
1813
0
            OSL_VERIFY( m_xProps->getPropertyValue( PROPERTY_IMAGE_POSITION ) >>= nImagePosition );
1814
0
            OSL_ENSURE( ( nImagePosition >= ImagePosition::LeftTop ) && ( nImagePosition <= ImagePosition::Centered ),
1815
0
                "OControlExport::exportImagePositionAttributes: don't know this image position!" );
1816
1817
0
            if ( ( nImagePosition < ImagePosition::LeftTop ) || ( nImagePosition > ImagePosition::Centered ) )
1818
                // this is important to prevent potential buffer overflows below, so don't optimize
1819
0
                nImagePosition = ImagePosition::Centered;
1820
1821
0
            if ( nImagePosition == ImagePosition::Centered )
1822
0
            {
1823
0
                AddAttribute( XML_NAMESPACE_FORM, GetXMLToken( XML_IMAGE_POSITION ), GetXMLToken( XML_CENTER ) );
1824
0
            }
1825
0
            else
1826
0
            {
1827
0
                const XMLTokenEnum eXmlImagePositions[] =
1828
0
                {
1829
0
                    XML_START, XML_END, XML_TOP, XML_BOTTOM
1830
0
                };
1831
0
                const XMLTokenEnum eXmlImageAligns[] =
1832
0
                {
1833
0
                    XML_START, XML_CENTER, XML_END
1834
0
                };
1835
1836
0
                XMLTokenEnum eXmlImagePosition = eXmlImagePositions[ nImagePosition / 3 ];
1837
0
                XMLTokenEnum eXmlImageAlign    = eXmlImageAligns   [ nImagePosition % 3 ];
1838
1839
0
                AddAttribute( XML_NAMESPACE_FORM, GetXMLToken( XML_IMAGE_POSITION ), GetXMLToken( eXmlImagePosition ) );
1840
0
                AddAttribute( XML_NAMESPACE_FORM, GetXMLToken( XML_IMAGE_ALIGN    ), GetXMLToken( eXmlImageAlign    ) );
1841
0
            }
1842
1843
0
            exportedProperty( PROPERTY_IMAGE_POSITION );
1844
            // some of the controls which have an ImagePosition also have an ImageAlign for compatibility
1845
            // reasons. Since the ImageAlign values simply represent a sub set of the ImagePosition values,
1846
            // we don't need to export ImageAlign anymore
1847
0
            exportedProperty( PROPERTY_IMAGE_ALIGN );
1848
0
        }
1849
0
        catch( const Exception& )
1850
0
        {
1851
0
            DBG_UNHANDLED_EXCEPTION("xmloff.forms");
1852
0
        }
1853
0
    }
1854
1855
    bool OControlExport::controlHasActiveDataBinding() const
1856
0
    {
1857
0
        try
1858
0
        {
1859
            // currently exchanging the data with a database column?
1860
0
            OUString sBoundFieldPropertyName( u"BoundField"_ustr );
1861
0
            if ( m_xPropertyInfo.is() && m_xPropertyInfo->hasPropertyByName( sBoundFieldPropertyName ) )
1862
0
            {
1863
0
                Reference< XPropertySet > xBoundField;
1864
0
                m_xProps->getPropertyValue( sBoundFieldPropertyName ) >>= xBoundField;
1865
0
                if ( xBoundField.is() )
1866
0
                    return true;
1867
0
            }
1868
1869
            // currently exchanging data with an external binding?
1870
0
            Reference< XBindableValue > xBindable( m_xProps, UNO_QUERY );
1871
0
            if ( xBindable.is() && xBindable->getValueBinding().is() )
1872
0
                return true;
1873
0
        }
1874
0
        catch( const Exception& )
1875
0
        {
1876
0
            TOOLS_WARN_EXCEPTION( "xmloff.forms", "OColumnExport::controlHasActiveDataBinding" );
1877
0
        }
1878
1879
0
        return false;
1880
0
    }
1881
1882
    bool OControlExport::controlHasUserSuppliedListEntries() const
1883
0
    {
1884
0
        try
1885
0
        {
1886
            // an external list source?
1887
0
            Reference< XListEntrySink > xEntrySink( m_xProps, UNO_QUERY );
1888
0
            if ( xEntrySink.is() && xEntrySink->getListEntrySource().is() )
1889
0
                return false;
1890
1891
0
            if ( m_xPropertyInfo.is() && m_xPropertyInfo->hasPropertyByName( PROPERTY_LISTSOURCETYPE ) )
1892
0
            {
1893
0
                ListSourceType eListSourceType = ListSourceType_VALUELIST;
1894
0
                OSL_VERIFY( m_xProps->getPropertyValue( PROPERTY_LISTSOURCETYPE ) >>= eListSourceType );
1895
0
                if ( eListSourceType == ListSourceType_VALUELIST )
1896
                    // for value lists, the list entries as entered by the user are used
1897
0
                    return true;
1898
1899
                // for every other type, the list entries are filled with some data obtained
1900
                // from a database - if and only if the ListSource property is not empty
1901
0
                return getScalarListSourceValue().isEmpty();
1902
0
            }
1903
0
        }
1904
0
        catch( const Exception& )
1905
0
        {
1906
0
            DBG_UNHANDLED_EXCEPTION("xmloff.forms");
1907
0
        }
1908
1909
0
        OSL_FAIL( "OControlExport::controlHasUserSuppliedListEntries: unreachable code!" );
1910
            // this method should be called for list and combo boxes only
1911
0
        return true;
1912
0
    }
1913
1914
    //= OColumnExport
1915
    OColumnExport::OColumnExport(IFormsExportContext& _rContext, const Reference< XPropertySet >& _rxControl, const OUString& _rControlId,
1916
        const Sequence< ScriptEventDescriptor >& _rEvents)
1917
0
        :OControlExport(_rContext, _rxControl, _rControlId, OUString(), _rEvents)
1918
0
    {
1919
0
    }
1920
1921
    OColumnExport::~OColumnExport()
1922
0
    {
1923
0
    }
1924
1925
    void OColumnExport::exportServiceNameAttribute()
1926
0
    {
1927
        // the attribute "service name" (which has a slightly different meaning for columns
1928
0
        DBG_CHECK_PROPERTY( PROPERTY_COLUMNSERVICENAME, OUString );
1929
0
        OUString sColumnServiceName;
1930
0
        m_xProps->getPropertyValue(PROPERTY_COLUMNSERVICENAME) >>= sColumnServiceName;
1931
        // the service name is a full qualified one (i.e. com.sun.star.form.TextField), but the
1932
        // real service name for the column (for use with the XGridColumnFactory) is only the last
1933
        // token of this complete name.
1934
0
        sal_Int32 nLastSep = sColumnServiceName.lastIndexOf('.');
1935
0
        OSL_ENSURE(-1 != nLastSep, "OColumnExport::startExportElement: invalid service name!");
1936
0
        sColumnServiceName = sColumnServiceName.copy(nLastSep + 1);
1937
0
        sColumnServiceName =
1938
0
            m_rContext.getGlobalContext().GetNamespaceMap().GetQNameByKey(
1939
0
                XML_NAMESPACE_OOO, sColumnServiceName );
1940
        // add the attribute
1941
0
        AddAttribute( OAttributeMetaData::getCommonControlAttributeNamespace(CCAFlags::ServiceName)
1942
0
                    , OAttributeMetaData::getCommonControlAttributeName(CCAFlags::ServiceName)
1943
0
                    , sColumnServiceName);
1944
        // flag the property as "handled"
1945
0
        exportedProperty(PROPERTY_COLUMNSERVICENAME);
1946
1947
0
    }
1948
1949
    OUString OColumnExport::getOuterXMLElementName() const
1950
0
    {
1951
0
        return u"column"_ustr;
1952
0
    }
1953
1954
    void OColumnExport::exportAttributes()
1955
0
    {
1956
0
        OControlExport::exportAttributes();
1957
1958
        // the attribute "label"
1959
0
        exportStringPropertyAttribute(
1960
0
            OAttributeMetaData::getCommonControlAttributeNamespace(CCAFlags::Label),
1961
0
            OAttributeMetaData::getCommonControlAttributeName(CCAFlags::Label),
1962
0
            PROPERTY_LABEL);
1963
1964
        // the style attribute
1965
0
        OUString sStyleName = m_rContext.getObjectStyleName( m_xProps );
1966
0
        if ( !sStyleName.isEmpty() )
1967
0
        {
1968
0
            AddAttribute(
1969
0
                OAttributeMetaData::getSpecialAttributeNamespace( SCAFlags::ColumnStyleName ),
1970
0
                OAttributeMetaData::getSpecialAttributeName( SCAFlags::ColumnStyleName ),
1971
0
                sStyleName
1972
0
            );
1973
0
        }
1974
0
    }
1975
1976
    void OColumnExport::examine()
1977
0
    {
1978
0
        OControlExport::examine();
1979
1980
        // grid columns miss some properties of the controls they're representing
1981
0
        m_nIncludeCommon &= ~CCAFlags(CCAFlags::For | CCAFlags::Printable | CCAFlags::TabIndex | CCAFlags::TabStop | CCAFlags::Label);
1982
0
        m_nIncludeSpecial &= ~SCAFlags(SCAFlags::EchoChar | SCAFlags::AutoCompletion | SCAFlags::Multiple | SCAFlags::MultiLine);
1983
1984
0
        if (FormComponentType::DATEFIELD != m_nClassId)
1985
            // except date fields, no column has the DropDown property
1986
0
            m_nIncludeCommon &= ~CCAFlags::Dropdown;
1987
0
    }
1988
1989
    //= OFormExport
1990
    OFormExport::OFormExport(IFormsExportContext& _rContext, const Reference< XPropertySet >& _rxForm,
1991
        const Sequence< ScriptEventDescriptor >& _rEvents)
1992
0
        :OElementExport(_rContext, _rxForm, _rEvents)
1993
0
        ,m_bCreateConnectionResourceElement(false)
1994
0
    {
1995
0
        OSL_ENSURE(m_xProps.is(), "OFormExport::OFormExport: invalid arguments!");
1996
0
    }
1997
1998
    OUString OFormExport::getXMLElementName() const
1999
0
    {
2000
0
        return u"form"_ustr;
2001
0
    }
2002
2003
    void OFormExport::exportSubTags()
2004
0
    {
2005
0
        if ( m_bCreateConnectionResourceElement && m_xProps.is() )
2006
0
        {
2007
0
            m_rContext.getGlobalContext().ClearAttrList();
2008
0
            OUString sPropValue;
2009
0
            m_xProps->getPropertyValue( PROPERTY_DATASOURCENAME ) >>= sPropValue; // if set it is a file url
2010
0
            if ( sPropValue.isEmpty() )
2011
0
                m_xProps->getPropertyValue( PROPERTY_URL ) >>= sPropValue;
2012
0
            if ( !sPropValue.isEmpty() )
2013
0
                AddAttribute(
2014
0
                    OAttributeMetaData::getCommonControlAttributeNamespace(CCAFlags::TargetLocation),
2015
0
                    OAttributeMetaData::getCommonControlAttributeName(CCAFlags::TargetLocation),
2016
0
                    m_rContext.getGlobalContext().GetRelativeReference(sPropValue));
2017
0
            if ( m_rContext.getGlobalContext().GetAttrList().getLength() )
2018
0
            {
2019
0
                SvXMLElementExport aFormElement(m_rContext.getGlobalContext(), XML_NAMESPACE_FORM, xmloff::token::XML_CONNECTION_RESOURCE, true, true);
2020
0
            }
2021
0
        }
2022
2023
        // let the base class export the remaining properties and the events
2024
0
        OElementExport::exportSubTags();
2025
        // loop through all children
2026
0
        Reference< XIndexAccess > xCollection(m_xProps, UNO_QUERY);
2027
0
        OSL_ENSURE(xCollection.is(), "OFormLayerXMLExport::implExportForm: a form which is not an index access? Suspicious!");
2028
2029
0
        if (xCollection.is())
2030
0
            m_rContext.exportCollectionElements(xCollection);
2031
0
    }
2032
2033
    void OFormExport::exportAttributes()
2034
0
    {
2035
0
        sal_Int32 i=0;
2036
2037
        // the string properties
2038
0
        {
2039
0
            static const FormAttributes eStringPropertyIds[] =
2040
0
            {
2041
0
                faName, /*faAction,*/ faCommand, faFilter, faOrder
2042
0
            };
2043
0
            static constexpr OUString aStringPropertyNames[] =
2044
0
            {
2045
0
                PROPERTY_NAME, /*PROPERTY_TARGETURL,*/ PROPERTY_COMMAND, PROPERTY_FILTER, PROPERTY_ORDER
2046
0
            };
2047
0
            static const sal_Int32 nIdCount = std::size(eStringPropertyIds);
2048
        #if OSL_DEBUG_LEVEL > 0
2049
            static const sal_Int32 nNameCount = std::size(aStringPropertyNames);
2050
            OSL_ENSURE((nIdCount == nNameCount),
2051
                "OFormExport::exportAttributes: somebody tampered with the maps (1)!");
2052
        #endif
2053
0
            for (i=0; i<nIdCount; ++i)
2054
0
                exportStringPropertyAttribute(
2055
0
                    OAttributeMetaData::getFormAttributeNamespace(eStringPropertyIds[i]),
2056
0
                    OAttributeMetaData::getFormAttributeName(eStringPropertyIds[i]),
2057
0
                    aStringPropertyNames[i]);
2058
2059
            // #i112082# xlink:type is added as part of exportTargetLocationAttribute
2060
2061
            // now export the data source name or databaselocation or connection resource
2062
0
            OUString sPropValue;
2063
0
            m_xProps->getPropertyValue( PROPERTY_DATASOURCENAME ) >>= sPropValue;
2064
0
            m_bCreateConnectionResourceElement = sPropValue.isEmpty();
2065
0
            if ( !m_bCreateConnectionResourceElement )
2066
0
            {
2067
0
                INetURLObject aURL(sPropValue);
2068
0
                m_bCreateConnectionResourceElement = ( aURL.GetProtocol() == INetProtocol::File );
2069
0
                if ( !m_bCreateConnectionResourceElement )
2070
0
                    exportStringPropertyAttribute(
2071
0
                        OAttributeMetaData::getFormAttributeNamespace(faDatasource),
2072
0
                        OAttributeMetaData::getFormAttributeName(faDatasource),
2073
0
                        PROPERTY_DATASOURCENAME);
2074
0
            }
2075
0
            else
2076
0
                exportedProperty(PROPERTY_URL);
2077
0
            if ( m_bCreateConnectionResourceElement )
2078
0
                exportedProperty(PROPERTY_DATASOURCENAME);
2079
0
        }
2080
2081
        // the boolean properties
2082
0
        {
2083
0
            static const FormAttributes eBooleanPropertyIds[] =
2084
0
            {
2085
0
                faAllowDeletes, faAllowInserts, faAllowUpdates, faApplyFilter, faEscapeProcessing, faIgnoreResult
2086
0
            };
2087
0
            static constexpr OUString pBooleanPropertyNames[] =
2088
0
            {
2089
0
                PROPERTY_ALLOWDELETES,
2090
0
                PROPERTY_ALLOWINSERTS,
2091
0
                PROPERTY_ALLOWUPDATES,
2092
0
                PROPERTY_APPLYFILTER,
2093
0
                PROPERTY_ESCAPEPROCESSING,
2094
0
                PROPERTY_IGNORERESULT
2095
0
            };
2096
0
            static const BoolAttrFlags nBooleanPropertyAttrFlags[] =
2097
0
            {
2098
0
                BoolAttrFlags::DefaultTrue, BoolAttrFlags::DefaultTrue, BoolAttrFlags::DefaultTrue, BoolAttrFlags::DefaultFalse, BoolAttrFlags::DefaultTrue, BoolAttrFlags::DefaultFalse
2099
0
            };
2100
0
            static const sal_Int32 nIdCount = std::size(eBooleanPropertyIds);
2101
        #if OSL_DEBUG_LEVEL > 0
2102
            static const sal_Int32 nNameCount = std::size(pBooleanPropertyNames);
2103
            static const sal_Int32 nFlagsCount = std::size(nBooleanPropertyAttrFlags);
2104
            OSL_ENSURE((nIdCount == nNameCount) && (nNameCount == nFlagsCount),
2105
                "OFormExport::exportAttributes: somebody tampered with the maps (2)!");
2106
        #endif
2107
0
            for (i=0; i<nIdCount; ++i)
2108
0
                exportBooleanPropertyAttribute(
2109
0
                    OAttributeMetaData::getFormAttributeNamespace(eBooleanPropertyIds[i]),
2110
0
                    OAttributeMetaData::getFormAttributeName(eBooleanPropertyIds[i]),
2111
0
                    pBooleanPropertyNames[i],
2112
0
                    nBooleanPropertyAttrFlags[i]
2113
0
                );
2114
0
        }
2115
2116
        // the enum properties
2117
0
        {
2118
0
            exportEnumPropertyAttribute(
2119
0
                OAttributeMetaData::getFormAttributeNamespace(faEnctype),
2120
0
                OAttributeMetaData::getFormAttributeName(faEnctype),
2121
0
                PROPERTY_SUBMIT_ENCODING,
2122
0
                aSubmitEncodingMap,
2123
0
                FormSubmitEncoding_URL,
2124
0
                false
2125
0
            );
2126
0
            exportEnumPropertyAttribute(
2127
0
                OAttributeMetaData::getFormAttributeNamespace(faMethod),
2128
0
                OAttributeMetaData::getFormAttributeName(faMethod),
2129
0
                PROPERTY_SUBMIT_METHOD,
2130
0
                aSubmitMethodMap,
2131
0
                FormSubmitMethod_GET,
2132
0
                false
2133
0
            );
2134
0
            exportEnumPropertyAttribute(
2135
0
                OAttributeMetaData::getFormAttributeNamespace(faCommandType),
2136
0
                OAttributeMetaData::getFormAttributeName(faCommandType),
2137
0
                PROPERTY_COMMAND_TYPE,
2138
0
                aCommandTypeMap,
2139
0
                CommandType::COMMAND,
2140
0
                false
2141
0
            );
2142
0
            exportEnumPropertyAttribute(
2143
0
                OAttributeMetaData::getFormAttributeNamespace(faNavigationMode),
2144
0
                OAttributeMetaData::getFormAttributeName(faNavigationMode),
2145
0
                PROPERTY_NAVIGATION,
2146
0
                aNavigationTypeMap,
2147
0
                NavigationBarMode_CURRENT,
2148
0
                false
2149
0
            );
2150
0
            exportEnumPropertyAttribute(
2151
0
                OAttributeMetaData::getFormAttributeNamespace(faTabbingCycle),
2152
0
                OAttributeMetaData::getFormAttributeName(faTabbingCycle),
2153
0
                PROPERTY_CYCLE,
2154
0
                aTabulatorCycleMap,
2155
0
                TabulatorCycle_RECORDS,
2156
0
                true
2157
0
            );
2158
0
        }
2159
2160
        // the service name
2161
0
        exportServiceNameAttribute();
2162
        // the target frame
2163
0
        exportTargetFrameAttribute();
2164
        // the target URL
2165
0
        exportTargetLocationAttribute(true);    // #i110911# add type attribute (for form, but not for control)
2166
2167
        // master fields
2168
0
        exportStringSequenceAttribute(
2169
0
            OAttributeMetaData::getFormAttributeNamespace(faMasterFields),
2170
0
            OAttributeMetaData::getFormAttributeName(faMasterFields),
2171
0
            PROPERTY_MASTERFIELDS);
2172
        // detail fields
2173
0
        exportStringSequenceAttribute(
2174
0
            OAttributeMetaData::getFormAttributeNamespace(faDetailFields),
2175
0
            OAttributeMetaData::getFormAttributeName(faDetailFields),
2176
0
            PROPERTY_DETAILFIELDS);
2177
0
    }
2178
}   // namespace xmloff
2179
2180
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */