Coverage Report

Created: 2025-12-31 10:39

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libreoffice/xmloff/source/forms/layerimport.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 "layerimport.hxx"
21
#include "formenums.hxx"
22
#include "elementimport.hxx"
23
#include "officeforms.hxx"
24
#include "strings.hxx"
25
#include <xmloff/xmlictxt.hxx>
26
#include <xmloff/xmlstyle.hxx>
27
#include <xmloff/families.hxx>
28
#include <xmloff/xmlimp.hxx>
29
#include <XMLEventImportHelper.hxx>
30
#include <xmloff/xmlnumfi.hxx>
31
#include <com/sun/star/util/XNumberFormatsSupplier.hpp>
32
#include <com/sun/star/form/FormSubmitEncoding.hpp>
33
#include <com/sun/star/form/FormSubmitMethod.hpp>
34
#include <com/sun/star/form/NavigationBarMode.hpp>
35
#include <com/sun/star/form/TabulatorCycle.hpp>
36
#include <com/sun/star/form/FormButtonType.hpp>
37
#include <com/sun/star/form/ListSourceType.hpp>
38
#include "formevents.hxx"
39
#include "formcellbinding.hxx"
40
#include <xmloff/xformsimport.hxx>
41
#include <xmloff/xmltoken.hxx>
42
#include <xmloff/xmlnamespace.hxx>
43
#include <rtl/strbuf.hxx>
44
#include <comphelper/diagnose_ex.hxx>
45
46
namespace xmloff
47
{
48
49
using namespace ::com::sun::star::uno;
50
using namespace ::com::sun::star::beans;
51
using namespace ::com::sun::star::container;
52
using namespace ::com::sun::star::drawing;
53
using namespace ::com::sun::star;
54
using namespace ::com::sun::star::util;
55
using namespace ::com::sun::star::form;
56
using namespace token;
57
58
//= OFormLayerXMLImport_Impl
59
OFormLayerXMLImport_Impl::OFormLayerXMLImport_Impl(SvXMLImport& _rImporter)
60
17.5k
    :m_rImporter(_rImporter)
61
17.5k
{
62
    // build the attribute2property map
63
    // string properties which are exported as attributes
64
17.5k
    m_aAttributeMetaData.addStringProperty(
65
17.5k
        OAttributeMetaData::getCommonControlAttributeToken(CCAFlags::Name), PROPERTY_NAME);
66
17.5k
    m_aAttributeMetaData.addStringProperty(
67
17.5k
        OAttributeMetaData::getSpecialAttributeToken(SCAFlags::GroupName), PROPERTY_GROUP_NAME);
68
17.5k
    m_aAttributeMetaData.addStringProperty(
69
17.5k
        OAttributeMetaData::getCommonControlAttributeToken(CCAFlags::Label), PROPERTY_LABEL);
70
17.5k
    m_aAttributeMetaData.addStringProperty(
71
17.5k
        OAttributeMetaData::getCommonControlAttributeToken(CCAFlags::TargetLocation), PROPERTY_TARGETURL);
72
17.5k
    m_aAttributeMetaData.addStringProperty(
73
17.5k
        OAttributeMetaData::getCommonControlAttributeToken(CCAFlags::Title), PROPERTY_TITLE);
74
17.5k
    m_aAttributeMetaData.addStringProperty(
75
17.5k
        OAttributeMetaData::getCommonControlAttributeToken(CCAFlags::TargetFrame), PROPERTY_TARGETFRAME);
76
17.5k
    m_aAttributeMetaData.addStringProperty(
77
17.5k
        OAttributeMetaData::getDatabaseAttributeToken(DAFlags::DataField), PROPERTY_DATAFIELD);
78
17.5k
    m_aAttributeMetaData.addStringProperty(
79
17.5k
        OAttributeMetaData::getFormAttributeToken(faCommand), PROPERTY_COMMAND);
80
17.5k
    m_aAttributeMetaData.addStringProperty(
81
17.5k
        OAttributeMetaData::getFormAttributeToken(faDatasource), PROPERTY_DATASOURCENAME);
82
17.5k
    m_aAttributeMetaData.addStringProperty(
83
17.5k
        OAttributeMetaData::getFormAttributeToken(faFilter), PROPERTY_FILTER);
84
17.5k
    m_aAttributeMetaData.addStringProperty(
85
17.5k
        OAttributeMetaData::getFormAttributeToken(faOrder), PROPERTY_ORDER);
86
87
    // properties not added because they're already present in another form
88
17.5k
    OSL_ENSURE(
89
17.5k
        OAttributeMetaData::getCommonControlAttributeName(CCAFlags::TargetLocation).equals(
90
17.5k
            OAttributeMetaData::getFormAttributeName(faAction)),
91
17.5k
        "OFormLayerXMLImport_Impl::OFormLayerXMLImport_Impl: invalid attribute names (1)!");
92
        // if this fails, we would have to add a translation from faAction->PROPERTY_TARGETURL
93
        // We did not because we already have one CCAFlags::TargetLocation->PROPERTY_TARGETURL,
94
        // and CCAFlags::TargetLocation and faAction should be represented by the same attribute
95
96
17.5k
    OSL_ENSURE(
97
17.5k
        OAttributeMetaData::getCommonControlAttributeName(CCAFlags::Name).equals(
98
17.5k
            OAttributeMetaData::getFormAttributeName(faName)),
99
17.5k
        "OFormLayerXMLImport_Impl::OFormLayerXMLImport_Impl: invalid attribute names (2)!");
100
        // the same for faName, CCAFlags::Name and PROPERTY_NAME
101
102
    // boolean properties which are exported as attributes
103
17.5k
    m_aAttributeMetaData.addBooleanProperty(
104
17.5k
        OAttributeMetaData::getCommonControlAttributeToken(CCAFlags::CurrentSelected), PROPERTY_STATE, false);
105
17.5k
    m_aAttributeMetaData.addBooleanProperty(
106
17.5k
        OAttributeMetaData::getCommonControlAttributeToken(CCAFlags::Disabled), PROPERTY_ENABLED, false, true);
107
17.5k
    m_aAttributeMetaData.addBooleanProperty(
108
17.5k
        OAttributeMetaData::getCommonControlAttributeToken(CCAFlags::Dropdown), PROPERTY_DROPDOWN, false);
109
17.5k
    m_aAttributeMetaData.addBooleanProperty(
110
17.5k
        OAttributeMetaData::getCommonControlAttributeToken(CCAFlags::Printable), PROPERTY_PRINTABLE, true);
111
17.5k
    m_aAttributeMetaData.addBooleanProperty(
112
17.5k
        OAttributeMetaData::getCommonControlAttributeToken(CCAFlags::ReadOnly), PROPERTY_READONLY, false);
113
17.5k
    m_aAttributeMetaData.addBooleanProperty(
114
17.5k
        OAttributeMetaData::getCommonControlAttributeToken(CCAFlags::Selected), PROPERTY_DEFAULT_STATE, false);
115
17.5k
    m_aAttributeMetaData.addBooleanProperty(
116
17.5k
        OAttributeMetaData::getCommonControlAttributeToken(CCAFlags::TabStop), PROPERTY_TABSTOP, true);
117
17.5k
    m_aAttributeMetaData.addBooleanProperty(
118
17.5k
        OAttributeMetaData::getDatabaseAttributeToken(DAFlags::ConvertEmpty), PROPERTY_EMPTY_IS_NULL, false);
119
17.5k
    m_aAttributeMetaData.addBooleanProperty(
120
17.5k
        OAttributeMetaData::getSpecialAttributeToken(SCAFlags::Validation), PROPERTY_STRICTFORMAT, false);
121
17.5k
    m_aAttributeMetaData.addBooleanProperty(
122
17.5k
        OAttributeMetaData::getSpecialAttributeToken(SCAFlags::MultiLine), PROPERTY_MULTILINE, false);
123
17.5k
    m_aAttributeMetaData.addBooleanProperty(
124
17.5k
        OAttributeMetaData::getSpecialAttributeToken(SCAFlags::AutoCompletion), PROPERTY_AUTOCOMPLETE, false);
125
17.5k
    m_aAttributeMetaData.addBooleanProperty(
126
17.5k
        OAttributeMetaData::getSpecialAttributeToken(SCAFlags::Multiple), PROPERTY_MULTISELECTION, false);
127
17.5k
    m_aAttributeMetaData.addBooleanProperty(
128
17.5k
        OAttributeMetaData::getSpecialAttributeToken(SCAFlags::DefaultButton), PROPERTY_DEFAULTBUTTON, false);
129
17.5k
    m_aAttributeMetaData.addBooleanProperty(
130
17.5k
        OAttributeMetaData::getSpecialAttributeToken(SCAFlags::IsTristate), PROPERTY_TRISTATE, false);
131
17.5k
    m_aAttributeMetaData.addBooleanProperty(
132
17.5k
        OAttributeMetaData::getFormAttributeToken(faAllowDeletes), PROPERTY_ALLOWDELETES, true);
133
17.5k
    m_aAttributeMetaData.addBooleanProperty(
134
17.5k
        OAttributeMetaData::getFormAttributeToken(faAllowInserts), PROPERTY_ALLOWINSERTS, true);
135
17.5k
    m_aAttributeMetaData.addBooleanProperty(
136
17.5k
        OAttributeMetaData::getFormAttributeToken(faAllowUpdates), PROPERTY_ALLOWUPDATES, true);
137
17.5k
    m_aAttributeMetaData.addBooleanProperty(
138
17.5k
        OAttributeMetaData::getFormAttributeToken(faApplyFilter), PROPERTY_APPLYFILTER, false);
139
17.5k
    m_aAttributeMetaData.addBooleanProperty(
140
17.5k
        OAttributeMetaData::getFormAttributeToken(faEscapeProcessing), PROPERTY_ESCAPEPROCESSING, true);
141
17.5k
    m_aAttributeMetaData.addBooleanProperty(
142
17.5k
        OAttributeMetaData::getFormAttributeToken(faIgnoreResult), PROPERTY_IGNORERESULT, false);
143
17.5k
    m_aAttributeMetaData.addBooleanProperty(
144
17.5k
        OAttributeMetaData::getSpecialAttributeToken( SCAFlags::Toggle ), PROPERTY_TOGGLE, false );
145
17.5k
    m_aAttributeMetaData.addBooleanProperty(
146
17.5k
        OAttributeMetaData::getSpecialAttributeToken( SCAFlags::FocusOnClick ), PROPERTY_FOCUS_ON_CLICK, true );
147
17.5k
    m_aAttributeMetaData.addBooleanProperty(
148
17.5k
        OAttributeMetaData::getDatabaseAttributeToken( DAFlags::InputRequired ), PROPERTY_INPUT_REQUIRED, false );
149
150
    // the int16 attributes
151
17.5k
    m_aAttributeMetaData.addInt16Property(
152
17.5k
        OAttributeMetaData::getCommonControlAttributeToken(CCAFlags::MaxLength), PROPERTY_MAXTEXTLENGTH);
153
17.5k
    m_aAttributeMetaData.addInt16Property(
154
17.5k
        OAttributeMetaData::getCommonControlAttributeToken(CCAFlags::Size), PROPERTY_LINECOUNT);
155
17.5k
    m_aAttributeMetaData.addInt16Property(
156
17.5k
        OAttributeMetaData::getCommonControlAttributeToken(CCAFlags::TabIndex), PROPERTY_TABINDEX);
157
17.5k
    m_aAttributeMetaData.addInt16Property(
158
17.5k
        OAttributeMetaData::getDatabaseAttributeToken(DAFlags::BoundColumn), PROPERTY_BOUNDCOLUMN);
159
160
    // the int32 attributes
161
17.5k
    m_aAttributeMetaData.addInt32Property(
162
17.5k
        OAttributeMetaData::getSpecialAttributeToken( SCAFlags::PageStepSize ), PROPERTY_BLOCK_INCREMENT );
163
164
    // the enum attributes
165
17.5k
    m_aAttributeMetaData.addEnumProperty(
166
17.5k
        OAttributeMetaData::getCommonControlAttributeToken( CCAFlags::VisualEffect ), PROPERTY_VISUAL_EFFECT,
167
17.5k
        aVisualEffectMap,
168
17.5k
        &::cppu::UnoType<sal_Int16>::get() );
169
17.5k
    m_aAttributeMetaData.addEnumProperty(
170
17.5k
        OAttributeMetaData::getCommonControlAttributeToken( CCAFlags::Orientation ), PROPERTY_ORIENTATION,
171
17.5k
        aOrientationMap,
172
17.5k
        &::cppu::UnoType<sal_Int32>::get() );
173
17.5k
    m_aAttributeMetaData.addEnumProperty(
174
17.5k
        OAttributeMetaData::getCommonControlAttributeToken(CCAFlags::ButtonType), PROPERTY_BUTTONTYPE,
175
17.5k
        aFormButtonTypeMap,
176
17.5k
        &::cppu::UnoType<FormButtonType>::get());
177
17.5k
    m_aAttributeMetaData.addEnumProperty(
178
17.5k
        OAttributeMetaData::getDatabaseAttributeToken(DAFlags::ListSource_TYPE), PROPERTY_LISTSOURCETYPE,
179
17.5k
        aListSourceTypeMap,
180
17.5k
        &::cppu::UnoType<ListSourceType>::get());
181
17.5k
    m_aAttributeMetaData.addEnumProperty(
182
17.5k
        OAttributeMetaData::getSpecialAttributeToken(SCAFlags::State), PROPERTY_DEFAULT_STATE,
183
17.5k
        aCheckStateMap,
184
17.5k
        &::cppu::UnoType<sal_Int16>::get());
185
17.5k
    m_aAttributeMetaData.addEnumProperty(
186
17.5k
        OAttributeMetaData::getSpecialAttributeToken(SCAFlags::CurrentState), PROPERTY_STATE,
187
17.5k
        aCheckStateMap,
188
17.5k
        &::cppu::UnoType<sal_Int16>::get());
189
17.5k
    m_aAttributeMetaData.addEnumProperty(
190
17.5k
        OAttributeMetaData::getFormAttributeToken(faEnctype), PROPERTY_SUBMIT_ENCODING,
191
17.5k
        aSubmitEncodingMap,
192
17.5k
        &::cppu::UnoType<FormSubmitEncoding>::get());
193
17.5k
    m_aAttributeMetaData.addEnumProperty(
194
17.5k
        OAttributeMetaData::getFormAttributeToken(faMethod), PROPERTY_SUBMIT_METHOD,
195
17.5k
        aSubmitMethodMap,
196
17.5k
        &::cppu::UnoType<FormSubmitMethod>::get());
197
17.5k
    m_aAttributeMetaData.addEnumProperty(
198
17.5k
        OAttributeMetaData::getFormAttributeToken(faCommandType), PROPERTY_COMMAND_TYPE,
199
17.5k
        aCommandTypeMap);
200
17.5k
    m_aAttributeMetaData.addEnumProperty(
201
17.5k
        OAttributeMetaData::getFormAttributeToken(faNavigationMode), PROPERTY_NAVIGATION,
202
17.5k
        aNavigationTypeMap,
203
17.5k
        &::cppu::UnoType<NavigationBarMode>::get());
204
17.5k
    m_aAttributeMetaData.addEnumProperty(
205
17.5k
        OAttributeMetaData::getFormAttributeToken(faTabbingCycle), PROPERTY_CYCLE,
206
17.5k
        aTabulatorCycleMap,
207
17.5k
        &::cppu::UnoType<TabulatorCycle>::get());
208
209
    // 'initialize'
210
17.5k
    m_aCurrentPageIds = m_aControlIds.end();
211
17.5k
}
212
213
OFormLayerXMLImport_Impl::~OFormLayerXMLImport_Impl()
214
17.5k
{}
215
216
void OFormLayerXMLImport_Impl::setAutoStyleContext(SvXMLStylesContext* _pNewContext)
217
14.3k
{
218
14.3k
    OSL_ENSURE(!m_xAutoStyles.is(), "OFormLayerXMLImport_Impl::setAutoStyleContext: not to be called twice!");
219
14.3k
    m_xAutoStyles.set(_pNewContext);
220
14.3k
}
221
222
void OFormLayerXMLImport_Impl::applyControlNumberStyle(const Reference< XPropertySet >& _rxControlModel, const OUString& _rControlNumberStyleName)
223
0
{
224
0
    OSL_ENSURE(_rxControlModel.is() && (!_rControlNumberStyleName.isEmpty()),
225
0
        "OFormLayerXMLImport_Impl::applyControlNumberStyle: invalid arguments (this will crash)!");
226
227
0
    OSL_ENSURE(m_xAutoStyles.is(), "OFormLayerXMLImport_Impl::applyControlNumberStyle: have no auto style context!");
228
0
    if (!m_xAutoStyles.is())
229
0
    {
230
0
        m_xAutoStyles.set(m_rImporter.GetShapeImport()->GetAutoStylesContext());
231
0
    }
232
233
0
    if (!m_xAutoStyles.is())
234
0
        return;
235
236
0
    const SvXMLStyleContext* pStyle = m_xAutoStyles->FindStyleChildContext(XmlStyleFamily::DATA_STYLE, _rControlNumberStyleName);
237
0
    if (pStyle)
238
0
    {
239
0
        const SvXMLNumFormatContext* pDataStyle = static_cast<const SvXMLNumFormatContext*>(pStyle);
240
241
        // set this format at the control model
242
0
        try
243
0
        {
244
            // the models number format supplier and formats
245
0
            Reference< XNumberFormatsSupplier > xFormatsSupplier;
246
0
            _rxControlModel->getPropertyValue(PROPERTY_FORMATSSUPPLIER) >>= xFormatsSupplier;
247
0
            Reference< XNumberFormats > xFormats;
248
0
            if (xFormatsSupplier.is())
249
0
                xFormats = xFormatsSupplier->getNumberFormats();
250
0
            OSL_ENSURE(xFormats.is(), "OFormLayerXMLImport_Impl::applyControlNumberStyle: could not obtain the controls number formats!");
251
252
            // obtain a key
253
0
            if (xFormats.is())
254
0
            {
255
0
                sal_Int32 nFormatKey = const_cast<SvXMLNumFormatContext*>(pDataStyle)->CreateAndInsert( xFormatsSupplier );
256
0
                OSL_ENSURE(-1 != nFormatKey, "OFormLayerXMLImport_Impl::applyControlNumberStyle: could not obtain a format key!");
257
258
                // set the format on the control model
259
0
                _rxControlModel->setPropertyValue(PROPERTY_FORMATKEY, Any(nFormatKey));
260
0
            }
261
0
        }
262
0
        catch(const Exception&)
263
0
        {
264
0
            OSL_FAIL("OFormLayerXMLImport_Impl::applyControlNumberStyle: couldn't set the format!");
265
0
        }
266
0
    }
267
0
    else
268
0
        OSL_FAIL("OFormLayerXMLImport_Impl::applyControlNumberStyle: did not find the style with the given name!");
269
0
}
270
271
void OFormLayerXMLImport_Impl::registerCellValueBinding( const Reference< XPropertySet >& _rxControlModel, const OUString& _rCellAddress )
272
0
{
273
0
    OSL_ENSURE( _rxControlModel.is() && !_rCellAddress.isEmpty(),
274
0
        "OFormLayerXMLImport_Impl::registerCellValueBinding: invalid arguments!" );
275
0
    m_aCellValueBindings.emplace_back( _rxControlModel, _rCellAddress );
276
0
}
277
278
void OFormLayerXMLImport_Impl::registerXFormsValueBinding(
279
    const Reference< XPropertySet >& _rxControlModel,
280
    const OUString& _rBindingID )
281
0
{
282
    // TODO: is an empty binding name allowed?
283
0
    OSL_ENSURE( _rxControlModel.is(), "need  model" );
284
285
0
    m_aXFormsValueBindings.emplace_back( _rxControlModel, _rBindingID );
286
0
}
287
288
void OFormLayerXMLImport_Impl::registerXFormsListBinding(
289
    const Reference< XPropertySet >& _rxControlModel,
290
    const OUString& _rBindingID )
291
0
{
292
    // TODO: is an empty binding name allowed?
293
0
    OSL_ENSURE( _rxControlModel.is(), "need  model" );
294
295
0
    m_aXFormsListBindings.emplace_back( _rxControlModel, _rBindingID );
296
0
}
297
298
void OFormLayerXMLImport_Impl::registerXFormsSubmission(
299
    const Reference< XPropertySet >& _rxControlModel,
300
    const OUString& _rSubmissionID )
301
0
{
302
    // TODO: is an empty binding name allowed?
303
0
    OSL_ENSURE( _rxControlModel.is(), "need  model" );
304
305
0
    m_aXFormsSubmissions.emplace_back( _rxControlModel, _rSubmissionID );
306
0
}
307
308
void OFormLayerXMLImport_Impl::registerCellRangeListSource( const Reference< XPropertySet >& _rxControlModel, const OUString& _rCellRangeAddress )
309
0
{
310
0
    OSL_ENSURE( _rxControlModel.is() && !_rCellRangeAddress.isEmpty(),
311
0
        "OFormLayerXMLImport_Impl::registerCellRangeListSource: invalid arguments!" );
312
0
    m_aCellRangeListSources.emplace_back( _rxControlModel, _rCellRangeAddress );
313
0
}
314
const SvXMLStyleContext* OFormLayerXMLImport_Impl::getStyleElement(const OUString& _rStyleName) const
315
0
{
316
0
    OSL_ENSURE( m_xAutoStyles.is(), "OFormLayerXMLImport_Impl::getStyleElement: have no auto style context!" );
317
        // did you use setAutoStyleContext?
318
319
0
    const SvXMLStyleContext* pControlStyle =
320
0
        m_xAutoStyles.is() ? m_xAutoStyles->FindStyleChildContext( XmlStyleFamily::TEXT_PARAGRAPH, _rStyleName ) : nullptr;
321
0
    OSL_ENSURE( pControlStyle || !m_xAutoStyles.is(),
322
0
                OStringBuffer("OFormLayerXMLImport_Impl::getStyleElement: did not find the style named \"" +
323
0
                    OUStringToOString(_rStyleName, RTL_TEXTENCODING_ASCII_US) +
324
0
                    "\"!").getStr() );
325
0
    return pControlStyle;
326
0
}
327
328
void OFormLayerXMLImport_Impl::enterEventContext()
329
0
{
330
    // install our own translation table. We need to disable the other tables because of name conflicts.
331
0
    m_rImporter.GetEventImport().PushTranslationTable();
332
0
    m_rImporter.GetEventImport().AddTranslationTable(g_pFormsEventTranslation);
333
0
}
334
335
void OFormLayerXMLImport_Impl::leaveEventContext()
336
0
{
337
    // install the original event tables.
338
0
    m_rImporter.GetEventImport().PopTranslationTable();
339
0
}
340
341
void OFormLayerXMLImport_Impl::registerControlId(const Reference< XPropertySet >& _rxControl, const OUString& _rId)
342
0
{
343
0
    OSL_ENSURE(m_aCurrentPageIds != m_aControlIds.end(), "OFormLayerXMLImport_Impl::registerControlId: no current page!");
344
0
    OSL_ENSURE(!_rId.isEmpty(), "OFormLayerXMLImport_Impl::registerControlId: invalid (empty) control id!");
345
346
0
    OSL_ENSURE(m_aCurrentPageIds->second.end() == m_aCurrentPageIds->second.find(_rId), "OFormLayerXMLImport_Impl::registerControlId: control id already used!");
347
0
    m_aCurrentPageIds->second[_rId] = _rxControl;
348
0
}
349
350
void OFormLayerXMLImport_Impl::registerControlReferences(const Reference< XPropertySet >& _rxControl, const OUString& _rReferringControls)
351
0
{
352
0
    OSL_ENSURE(!_rReferringControls.isEmpty(), "OFormLayerXMLImport_Impl::registerControlReferences: invalid (empty) control id list!");
353
0
    OSL_ENSURE(_rxControl.is(), "OFormLayerXMLImport_Impl::registerControlReferences: invalid (NULL) control!");
354
0
    m_aControlReferences.emplace_back( _rxControl, _rReferringControls );
355
0
}
356
357
void OFormLayerXMLImport_Impl::startPage(const Reference< XDrawPage >& _rxDrawPage)
358
32.5k
{
359
32.5k
    m_xCurrentPageFormsSupp.clear();
360
361
32.5k
    OSL_ENSURE(_rxDrawPage.is(), "OFormLayerXMLImport_Impl::startPage: NULL page!");
362
32.5k
    m_xCurrentPageFormsSupp.set(_rxDrawPage, css::uno::UNO_QUERY);
363
32.5k
    OSL_ENSURE( m_xCurrentPageFormsSupp.is(), "OFormLayerXMLImport_Impl::startPage: invalid draw page (no XFormsSupplier)!" );
364
32.5k
    if ( !m_xCurrentPageFormsSupp.is() )
365
0
        return;
366
367
    // add a new entry to our page map
368
32.5k
    ::std::pair< MapDrawPage2Map::iterator, bool > aPagePosition = m_aControlIds.emplace(_rxDrawPage, MapString2PropertySet());
369
32.5k
    OSL_ENSURE(aPagePosition.second, "OFormLayerXMLImport_Impl::startPage: already imported this page!");
370
32.5k
    m_aCurrentPageIds = aPagePosition.first;
371
32.5k
}
372
373
void OFormLayerXMLImport_Impl::endPage()
374
28.4k
{
375
28.4k
    OSL_ENSURE( m_xCurrentPageFormsSupp.is(), "OFormLayerXMLImport_Impl::endPage: sure you called startPage before?" );
376
377
    // do some knittings for the controls which are referring to each other
378
28.4k
    try
379
28.4k
    {
380
28.4k
        static const sal_Unicode s_nSeparator = ',';
381
28.4k
        OUString sCurrentReferring;
382
28.4k
        OUString sSeparator(&s_nSeparator, 1);
383
28.4k
        Reference< XPropertySet > xCurrentReferring;
384
28.4k
        sal_Int32 nSeparator, nPrevSep;
385
28.4k
        for ( const auto& rReferences : m_aControlReferences )
386
0
        {
387
            // the list of control ids is comma separated
388
389
            // in a list of n ids there are only n-1 separators ... have to catch this last id
390
            // -> normalize the list
391
0
            OUString sReferring = rReferences.second + sSeparator;
392
393
0
            nPrevSep = -1;
394
0
            while (-1 != (nSeparator = sReferring.indexOf(s_nSeparator, nPrevSep + 1)))
395
0
            {
396
0
                sCurrentReferring = sReferring.copy(nPrevSep + 1, nSeparator - nPrevSep - 1);
397
0
                xCurrentReferring = lookupControlId(sCurrentReferring);
398
0
                if (xCurrentReferring.is())
399
                    // if this condition fails, this is an error, but lookupControlId should have asserted this ...
400
0
                    xCurrentReferring->setPropertyValue( PROPERTY_CONTROLLABEL, Any( rReferences.first ) );
401
402
0
                nPrevSep = nSeparator;
403
0
            }
404
0
        }
405
28.4k
    }
406
28.4k
    catch(Exception&)
407
28.4k
    {
408
0
        TOOLS_WARN_EXCEPTION("xmloff.forms",
409
0
                             "unable to knit the control references (caught an exception)!");
410
0
    }
411
412
    // now that we have all children of the forms collection, attach the events
413
28.4k
    Reference< XIndexAccess > xIndexContainer;
414
28.4k
    if ( m_xCurrentPageFormsSupp.is() && m_xCurrentPageFormsSupp->hasForms() )
415
0
        xIndexContainer.set(m_xCurrentPageFormsSupp->getForms(), css::uno::UNO_QUERY);
416
28.4k
    if ( xIndexContainer.is() )
417
0
        ODefaultEventAttacherManager::setEvents( xIndexContainer );
418
419
    // clear the structures for the control references.
420
28.4k
    m_aControlReferences.clear();
421
422
    // and no we have no current page anymore
423
28.4k
    m_aCurrentPageIds = m_aControlIds.end();
424
28.4k
}
425
426
Reference< XPropertySet > OFormLayerXMLImport_Impl::lookupControlId(const OUString& _rControlId)
427
0
{
428
0
    OSL_ENSURE(m_aCurrentPageIds != m_aControlIds.end(), "OFormLayerXMLImport_Impl::lookupControlId: no current page!");
429
0
    Reference< XPropertySet > xReturn;
430
0
    if (m_aCurrentPageIds != m_aControlIds.end())
431
0
    {
432
0
        MapString2PropertySet::const_iterator aPos = m_aCurrentPageIds->second.find(_rControlId);
433
0
        if (m_aCurrentPageIds->second.end() != aPos)
434
0
            xReturn = aPos->second;
435
0
        else
436
0
            SAL_WARN("xmloff", "unknown control id " << _rControlId);
437
0
    }
438
0
    return xReturn;
439
0
}
440
441
SvXMLImportContext* OFormLayerXMLImport_Impl::createOfficeFormsContext(
442
    SvXMLImport& _rImport)
443
139
{
444
139
    return new OFormsRootImport( _rImport );
445
139
}
446
447
SvXMLImportContext* OFormLayerXMLImport_Impl::createContext(
448
    sal_Int32 nElement,
449
    const Reference< xml::sax::XFastAttributeList >&)
450
1
{
451
1
    SvXMLImportContext* pContext = nullptr;
452
1
    if ( (nElement & TOKEN_MASK) == XML_FORM )
453
0
    {
454
0
        if ( m_xCurrentPageFormsSupp.is() )
455
0
            pContext = new OFormImport(*this, *this, m_xCurrentPageFormsSupp->getForms() );
456
0
    }
457
1
    else if ( nElement == XML_ELEMENT(XFORMS, XML_MODEL) )
458
0
    {
459
0
        pContext = createXFormsModelContext( m_rImporter );
460
0
    }
461
1
    else
462
1
        SAL_WARN("xmloff", "unknown element " << SvXMLImport::getPrefixAndNameFromToken(nElement));
463
464
1
    return pContext;
465
1
}
466
467
void OFormLayerXMLImport_Impl::documentDone( )
468
4.36k
{
469
4.36k
    SvXMLImport& rImport = getGlobalContext();
470
4.36k
    if ( !( rImport.getImportFlags() & SvXMLImportFlags::CONTENT ) )
471
0
        return;
472
473
    // create (and bind) the spreadsheet cell bindings
474
4.36k
    if  (   !m_aCellValueBindings.empty()
475
0
        &&  FormCellBindingHelper::isCellBindingAllowed( rImport.GetModel() )
476
4.36k
        )
477
0
    {
478
0
        for ( const auto& rCellBindings : m_aCellValueBindings )
479
0
        {
480
0
            try
481
0
            {
482
0
                FormCellBindingHelper aHelper( rCellBindings.first, rImport.GetModel() );
483
0
                OSL_ENSURE( aHelper.isCellBindingAllowed(), "OFormLayerXMLImport_Impl::documentDone: can't bind this control model!" );
484
0
                if ( aHelper.isCellBindingAllowed() )
485
0
                {
486
                    // There are special bindings for listboxes. See
487
                    // OListAndComboImport::doRegisterCellValueBinding for a comment on this HACK.
488
0
                    OUString sBoundCellAddress( rCellBindings.second );
489
0
                    sal_Int32 nIndicator = sBoundCellAddress.lastIndexOf( ":index" );
490
491
0
                    bool bUseIndexBinding = false;
492
0
                    if ( nIndicator != -1 )
493
0
                    {
494
0
                        sBoundCellAddress = sBoundCellAddress.copy( 0, nIndicator );
495
0
                        bUseIndexBinding = true;
496
0
                    }
497
498
0
                    aHelper.setBinding( aHelper.createCellBindingFromStringAddress( sBoundCellAddress, bUseIndexBinding ) );
499
0
                }
500
0
            }
501
0
            catch( const Exception& )
502
0
            {
503
0
                TOOLS_WARN_EXCEPTION("xmloff.forms",
504
0
                                     "caught an exception while binding to a cell!");
505
0
            }
506
0
        }
507
0
        m_aCellValueBindings.clear();
508
0
    }
509
510
    // the same for the spreadsheet cell range list sources
511
4.36k
    if  (   !m_aCellRangeListSources.empty()
512
0
        &&  FormCellBindingHelper::isListCellRangeAllowed( rImport.GetModel() )
513
4.36k
        )
514
0
    {
515
0
        for ( const auto& rRangeBindings : m_aCellRangeListSources )
516
0
        {
517
0
            try
518
0
            {
519
0
                FormCellBindingHelper aHelper( rRangeBindings.first, rImport.GetModel() );
520
0
                OSL_ENSURE( aHelper.isListCellRangeAllowed(), "OFormLayerXMLImport_Impl::documentDone: can't bind this control model!" );
521
0
                if ( aHelper.isListCellRangeAllowed() )
522
0
                {
523
0
                    aHelper.setListSource( aHelper.createCellListSourceFromStringAddress( rRangeBindings.second ) );
524
0
                }
525
0
            }
526
0
            catch( const Exception& )
527
0
            {
528
0
                TOOLS_WARN_EXCEPTION("xmloff.forms",
529
0
                                     "caught an exception while binding to a cell range!");
530
0
            }
531
0
        }
532
0
        m_aCellRangeListSources.clear();
533
0
    }
534
535
    // process XForms-bindings; call registerXFormsValueBinding for each
536
4.36k
    for (const auto& aXFormsValueBinding : m_aXFormsValueBindings)
537
0
        bindXFormsValueBinding(rImport.GetModel(), aXFormsValueBinding);
538
    // same for list bindings
539
4.36k
    for (const auto& aXFormsListBindings : m_aXFormsListBindings)
540
0
        bindXFormsListBinding(rImport.GetModel(), aXFormsListBindings);
541
    // same for submissions
542
4.36k
    for (const auto& aXFormsSubmission : m_aXFormsSubmissions)
543
0
        bindXFormsSubmission(rImport.GetModel(), aXFormsSubmission);
544
4.36k
}
545
546
}   // namespace xmloff
547
548
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */