Coverage Report

Created: 2026-11-06 11:29

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libreoffice/xmloff/source/text/txtimp.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 <memory>
21
#include <optional>
22
#include <tuple>
23
#include <vector>
24
25
#include <com/sun/star/container/XEnumerationAccess.hpp>
26
#include <com/sun/star/frame/XModel.hpp>
27
#include <com/sun/star/lang/XMultiServiceFactory.hpp>
28
#include <com/sun/star/style/XStyleFamiliesSupplier.hpp>
29
#include <com/sun/star/text/ReferenceFieldSource.hpp>
30
#include <com/sun/star/text/XChapterNumberingSupplier.hpp>
31
#include <com/sun/star/text/XTextFrame.hpp>
32
#include <com/sun/star/text/XTextFieldsSupplier.hpp>
33
#include <com/sun/star/text/XTextFramesSupplier.hpp>
34
#include <com/sun/star/text/XTextGraphicObjectsSupplier.hpp>
35
#include <com/sun/star/text/XTextEmbeddedObjectsSupplier.hpp>
36
#include <com/sun/star/text/XFormField.hpp>
37
#include <com/sun/star/ucb/XAnyCompare.hpp>
38
#include <com/sun/star/container/XNamed.hpp>
39
#include <com/sun/star/style/XStyle.hpp>
40
#include <xmloff/xmlnamespace.hxx>
41
#include <xmloff/txtstyli.hxx>
42
#include <xmloff/xmlnumi.hxx>
43
#include <xmloff/maptype.hxx>
44
45
#include <sal/log.hxx>
46
#include "txtparai.hxx"
47
#include <xmloff/txtprmap.hxx>
48
#include <xmloff/txtimppr.hxx>
49
#include <xmloff/xmlimp.hxx>
50
#include <txtvfldi.hxx>
51
#include <xmloff/i18nmap.hxx>
52
#include "XMLTextListItemContext.hxx"
53
#include "XMLTextListBlockContext.hxx"
54
#include "XMLTextFrameContext.hxx"
55
#include "XMLTextFrameHyperlinkContext.hxx"
56
#include "XMLSectionImportContext.hxx"
57
#include "XMLIndexTOCContext.hxx"
58
#include <xmloff/XMLEventsImportContext.hxx>
59
#include "XMLTrackedChangesImportContext.hxx"
60
#include "XMLChangeImportContext.hxx"
61
#include "XMLAutoMarkFileContext.hxx"
62
#include <xmloff/ProgressBarHelper.hxx>
63
64
#include "XMLCalculationSettingsContext.hxx"
65
#include <XMLNumberStylesImport.hxx>
66
#include <PageMasterStyleMap.hxx>
67
#include <PageMasterPropHdlFactory.hxx>
68
// XML import: reconstruction of assignment of paragraph style to outline levels (#i69629#)
69
#include <com/sun/star/beans/XPropertyState.hpp>
70
#include <txtlists.hxx>
71
#include <xmloff/odffields.hxx>
72
73
using ::com::sun::star::ucb::XAnyCompare;
74
75
using namespace ::com::sun::star;
76
using namespace ::com::sun::star::uno;
77
using namespace ::com::sun::star::beans;
78
using namespace ::com::sun::star::text;
79
using namespace ::com::sun::star::frame;
80
using namespace ::com::sun::star::style;
81
using namespace ::com::sun::star::container;
82
using namespace ::com::sun::star::drawing;
83
using namespace ::com::sun::star::xml::sax;
84
using namespace ::com::sun::star::lang;
85
using namespace ::xmloff::token;
86
using namespace ::com::sun::star::ucb;
87
88
89
struct XMLTextImportHelper::Impl
90
{
91
    std::optional< std::vector<OUString> > m_xPrevFrmNames;
92
    std::optional< std::vector<OUString> > m_xNextFrmNames;
93
    std::unique_ptr<XMLTextListsHelper> m_xTextListsHelper;
94
95
    rtl::Reference<SvXMLStylesContext> m_xAutoStyles;
96
97
    std::unique_ptr< SvXMLImportPropertyMapper > m_xParaImpPrMap;
98
    std::unique_ptr< SvXMLImportPropertyMapper > m_xTextImpPrMap;
99
    std::unique_ptr< SvXMLImportPropertyMapper > m_xFrameImpPrMap;
100
    std::unique_ptr< SvXMLImportPropertyMapper > m_xSectionImpPrMap;
101
    std::unique_ptr< SvXMLImportPropertyMapper > m_xRubyImpPrMap;
102
103
    std::unique_ptr<SvI18NMap> m_xRenameMap;
104
105
    /* Change and extend data structure:
106
       - data structure contains candidates of paragraph styles, which
107
         will be assigned to the outline style
108
       - data structure contains more than one candidate for each list level
109
         of the outline style (#i69629#)
110
    */
111
    std::unique_ptr< std::vector< OUString > []>
112
        m_xOutlineStylesCandidates;
113
114
    // start range, xml:id, RDFa stuff
115
    typedef std::tuple<
116
        uno::Reference<text::XTextRange>, OUString,
117
        std::shared_ptr< ::xmloff::ParsedRDFaAttributes > >
118
            BookmarkMapEntry_t;
119
    /// start ranges for open bookmarks
120
    std::map< OUString, BookmarkMapEntry_t > m_BookmarkStartRanges;
121
122
    std::vector< OUString > m_BookmarkVector;
123
124
    /// name of the last 'open' redline that started between paragraphs
125
    OUString m_sOpenRedlineIdentifier;
126
127
    // Used for frame deduplication, the name of the last frame imported directly before the current one
128
    OUString msLastImportedFrameName;
129
130
    std::map< OUString, bool > m_bBookmarkHidden;
131
    std::map< OUString, OUString > m_sBookmarkCondition;
132
133
    uno::Reference<text::XText> m_xText;
134
    uno::Reference<text::XTextCursor> m_xCursor;
135
    uno::Reference<text::XTextRange> m_xCursorAsRange;
136
    uno::Reference<container::XNameContainer> m_xParaStyles;
137
    uno::Reference<container::XNameContainer> m_xTextStyles;
138
    uno::Reference<container::XNameContainer> m_xNumStyles;
139
    uno::Reference<container::XNameContainer> m_xFrameStyles;
140
    uno::Reference<container::XNameContainer> m_xPageStyles;
141
    uno::Reference<container::XNameContainer> m_xCellStyles;
142
    uno::Reference<container::XIndexReplace> m_xChapterNumbering;
143
    uno::Reference<container::XNameAccess> m_xTextFrames;
144
    uno::Reference<container::XNameAccess> m_xGraphics;
145
    uno::Reference<container::XNameAccess> m_xObjects;
146
    uno::Reference<lang::XMultiServiceFactory> m_xServiceFactory;
147
148
    SvXMLImport & m_rSvXMLImport;
149
150
    bool m_bInsertMode : 1;
151
    bool m_bStylesOnlyMode : 1;
152
    bool m_bBlockMode : 1;
153
    bool m_bProgress : 1;
154
    bool m_bOrganizerMode : 1;
155
    bool m_bBodyContentStarted : 1;
156
157
    /// Are we inside a <text:deletion> element (deleted redline section)
158
    bool m_bInsideDeleteContext : 1;
159
160
    typedef ::std::pair< OUString, OUString> field_name_type_t;
161
    typedef ::std::pair< OUString, OUString > field_param_t;
162
    typedef ::std::vector< field_param_t > field_params_t;
163
    typedef ::std::tuple<field_name_type_t, field_params_t, uno::Reference<text::XFormField>, uno::Reference<text::XTextRange>> field_stack_item_t;
164
    typedef ::std::stack< field_stack_item_t > field_stack_t;
165
166
    field_stack_t m_FieldStack;
167
168
    OUString m_sCellParaStyleDefault;
169
170
    std::optional<std::map<OUString, OUString>> m_xCrossRefHeadingBookmarkMap;
171
172
    Impl(       uno::Reference<frame::XModel> const& rModel,
173
                SvXMLImport & rImport,
174
                bool const bInsertMode, bool const bStylesOnlyMode,
175
                bool const bProgress, bool const bBlockMode,
176
                bool const bOrganizerMode)
177
22.9k
        :   m_xTextListsHelper( new XMLTextListsHelper() )
178
        // XML import: reconstruction of assignment of paragraph style to outline levels (#i69629#)
179
22.9k
        ,   m_xServiceFactory( rModel, UNO_QUERY )
180
22.9k
        ,   m_rSvXMLImport( rImport )
181
22.9k
        ,   m_bInsertMode( bInsertMode )
182
22.9k
        ,   m_bStylesOnlyMode( bStylesOnlyMode )
183
22.9k
        ,   m_bBlockMode( bBlockMode )
184
22.9k
        ,   m_bProgress( bProgress )
185
22.9k
        ,   m_bOrganizerMode( bOrganizerMode )
186
22.9k
        ,   m_bBodyContentStarted( true )
187
22.9k
        ,   m_bInsideDeleteContext( false )
188
22.9k
    {
189
22.9k
    }
190
    Impl(const Impl&) = delete;
191
    Impl& operator=(const Impl&) = delete;
192
193
    void InitOutlineStylesCandidates()
194
159k
    {
195
159k
        if (!m_xOutlineStylesCandidates)
196
2.48k
        {
197
2.48k
            size_t const size(m_xChapterNumbering->getCount());
198
2.48k
            m_xOutlineStylesCandidates.reset(
199
2.48k
                new ::std::vector< OUString >[size] );
200
2.48k
        }
201
159k
    }
202
203
};
204
205
206
uno::Reference< text::XText > & XMLTextImportHelper::GetText()
207
260k
{
208
260k
    return m_xImpl->m_xText;
209
260k
}
210
211
uno::Reference< text::XTextCursor > & XMLTextImportHelper::GetCursor()
212
123k
{
213
123k
    return m_xImpl->m_xCursor;
214
123k
}
215
216
uno::Reference< text::XTextRange > & XMLTextImportHelper::GetCursorAsRange()
217
485k
{
218
485k
    return m_xImpl->m_xCursorAsRange;
219
485k
}
220
221
bool XMLTextImportHelper::IsInsertMode() const
222
34.3k
{
223
34.3k
    return m_xImpl->m_bInsertMode;
224
34.3k
}
225
226
bool XMLTextImportHelper::IsStylesOnlyMode() const
227
209
{
228
209
    return m_xImpl->m_bStylesOnlyMode;
229
209
}
230
231
bool XMLTextImportHelper::IsBlockMode() const
232
22.9k
{
233
22.9k
    return m_xImpl->m_bBlockMode;
234
22.9k
}
235
236
bool XMLTextImportHelper::IsOrganizerMode() const
237
209
{
238
209
    return m_xImpl->m_bOrganizerMode;
239
209
}
240
241
bool XMLTextImportHelper::IsProgress() const
242
0
{
243
0
    return m_xImpl->m_bProgress;
244
0
}
245
246
uno::Reference<container::XNameContainer> const&
247
XMLTextImportHelper::GetParaStyles() const
248
977
{
249
977
    return m_xImpl->m_xParaStyles;
250
977
}
251
252
uno::Reference<container::XNameContainer> const&
253
XMLTextImportHelper::GetTextStyles() const
254
11.0k
{
255
11.0k
    return m_xImpl->m_xTextStyles;
256
11.0k
}
257
258
uno::Reference<container::XNameContainer> const&
259
XMLTextImportHelper::GetNumberingStyles() const
260
1.96k
{
261
1.96k
    return m_xImpl->m_xNumStyles;
262
1.96k
}
263
264
uno::Reference<container::XNameContainer> const&
265
XMLTextImportHelper::GetFrameStyles() const
266
44.6k
{
267
44.6k
    return m_xImpl->m_xFrameStyles;
268
44.6k
}
269
270
uno::Reference<container::XNameContainer> const&
271
XMLTextImportHelper::GetPageStyles() const
272
31.2k
{
273
31.2k
    return m_xImpl->m_xPageStyles;
274
31.2k
}
275
276
uno::Reference<container::XNameContainer> const&
277
XMLTextImportHelper::GetCellStyles() const
278
5.39k
{
279
5.39k
    return m_xImpl->m_xCellStyles;
280
5.39k
}
281
282
uno::Reference<container::XIndexReplace> const&
283
XMLTextImportHelper::GetChapterNumbering() const
284
6.62k
{
285
6.62k
    return m_xImpl->m_xChapterNumbering;
286
6.62k
}
287
288
SvXMLImportPropertyMapper*
289
XMLTextImportHelper::GetParaImportPropertySetMapper() const
290
206k
{
291
206k
    return m_xImpl->m_xParaImpPrMap.get();
292
206k
}
293
294
SvXMLImportPropertyMapper*
295
XMLTextImportHelper::GetTextImportPropertySetMapper() const
296
30.5k
{
297
30.5k
    return m_xImpl->m_xTextImpPrMap.get();
298
30.5k
}
299
300
SvXMLImportPropertyMapper*
301
XMLTextImportHelper::GetSectionImportPropertySetMapper() const
302
351
{
303
351
    return m_xImpl->m_xSectionImpPrMap.get();
304
351
}
305
306
SvXMLImportPropertyMapper*
307
XMLTextImportHelper::GetRubyImportPropertySetMapper() const
308
512
{
309
512
    return m_xImpl->m_xRubyImpPrMap.get();
310
512
}
311
312
void XMLTextImportHelper::SetInsideDeleteContext(bool const bNew)
313
0
{
314
0
    m_xImpl->m_bInsideDeleteContext = bNew;
315
0
}
316
317
bool XMLTextImportHelper::IsInsideDeleteContext() const
318
63.8k
{
319
63.8k
    return m_xImpl->m_bInsideDeleteContext;
320
63.8k
}
321
322
SvXMLImport & XMLTextImportHelper::GetXMLImport()
323
169k
{
324
169k
    return m_xImpl->m_rSvXMLImport;
325
169k
}
326
327
XMLTextListsHelper & XMLTextImportHelper::GetTextListHelper()
328
772k
{
329
772k
    return *m_xImpl->m_xTextListsHelper;
330
772k
}
331
332
namespace
333
{
334
    class FieldParamImporter
335
    {
336
        public:
337
            typedef std::pair<OUString,OUString> field_param_t;
338
            typedef std::vector<field_param_t> field_params_t;
339
            FieldParamImporter(const field_params_t* const pInParams, Reference<XNameContainer> const & xOutParams)
340
12
                : m_pInParams(pInParams)
341
12
                , m_xOutParams(xOutParams)
342
12
            { };
343
            void Import();
344
345
        private:
346
            const field_params_t* const m_pInParams;
347
            Reference<XNameContainer> m_xOutParams;
348
    };
349
350
    void FieldParamImporter::Import()
351
12
    {
352
12
        ::std::vector<OUString> vListEntries;
353
12
        ::std::map<OUString, Any> vOutParams;
354
12
        for(const auto& rCurrent : *m_pInParams)
355
25
        {
356
25
            if(rCurrent.first == ODF_FORMDROPDOWN_RESULT)
357
0
            {
358
                // sal_Int32
359
0
                vOutParams[rCurrent.first] <<= rCurrent.second.toInt32();
360
0
            }
361
25
            else if(rCurrent.first == ODF_FORMCHECKBOX_RESULT)
362
0
            {
363
                // bool
364
0
                vOutParams[rCurrent.first] <<= rCurrent.second.toBoolean();
365
0
            }
366
25
            else if(rCurrent.first == ODF_FORMDROPDOWN_LISTENTRY)
367
0
            {
368
                // sequence
369
0
                vListEntries.push_back(rCurrent.second);
370
0
            }
371
25
            else
372
25
                vOutParams[rCurrent.first] <<= rCurrent.second;
373
25
        }
374
12
        if(!vListEntries.empty())
375
0
        {
376
0
            Sequence<OUString> vListEntriesSeq(vListEntries.size());
377
0
            copy(vListEntries.begin(), vListEntries.end(), vListEntriesSeq.getArray());
378
0
            vOutParams[ODF_FORMDROPDOWN_LISTENTRY] <<= vListEntriesSeq;
379
0
        }
380
12
        for(const auto& rCurrent : vOutParams)
381
24
        {
382
24
            try
383
24
            {
384
24
                m_xOutParams->insertByName(rCurrent.first, rCurrent.second);
385
24
            }
386
24
            catch(const ElementExistException&)
387
24
            {
388
0
                SAL_INFO("xmloff.text", "duplicate fieldmark param");
389
0
            }
390
24
        }
391
12
    }
392
}
393
394
XMLTextImportHelper::XMLTextImportHelper(
395
        uno::Reference<frame::XModel> const& rModel,
396
        SvXMLImport& rImport,
397
        bool const bInsertMode, bool const bStylesOnlyMode,
398
        bool const bProgress, bool const bBlockMode,
399
        bool const bOrganizerMode)
400
22.9k
    : m_xImpl( new Impl(rModel, rImport, bInsertMode, bStylesOnlyMode,
401
22.9k
                    bProgress, bBlockMode, bOrganizerMode) )
402
22.9k
    , m_xBackpatcherImpl( MakeBackpatcherImpl() )
403
22.9k
{
404
22.9k
    static constexpr OUString s_PropNameDefaultListId = u"DefaultListId"_ustr;
405
406
22.9k
    Reference< XChapterNumberingSupplier > xCNSupplier( rModel, UNO_QUERY );
407
408
22.9k
    if (xCNSupplier.is())
409
22.9k
    {
410
        // note: m_xChapterNumbering is accessed to import some fields
411
22.9k
        m_xImpl->m_xChapterNumbering = xCNSupplier->getChapterNumberingRules();
412
        // the AutoCorrect document doesn't have a proper outline numbering
413
22.9k
        if (!IsBlockMode() && m_xImpl->m_xChapterNumbering.is())
414
22.9k
        {
415
22.9k
            Reference< XPropertySet > const xNumRuleProps(
416
22.9k
                m_xImpl->m_xChapterNumbering, UNO_QUERY);
417
22.9k
            if ( xNumRuleProps.is() )
418
22.9k
            {
419
22.9k
                Reference< XPropertySetInfo > xNumRulePropSetInfo(
420
22.9k
                                            xNumRuleProps->getPropertySetInfo());
421
22.9k
                if (xNumRulePropSetInfo.is() &&
422
22.9k
                    xNumRulePropSetInfo->hasPropertyByName(
423
22.9k
                         s_PropNameDefaultListId))
424
22.9k
                {
425
22.9k
                    OUString sListId;
426
22.9k
                    xNumRuleProps->getPropertyValue(s_PropNameDefaultListId)
427
22.9k
                        >>= sListId;
428
22.9k
                    assert( !sListId.isEmpty() &&
429
22.9k
                                "no default list id found at chapter numbering rules instance. Serious defect." );
430
22.9k
                    if ( !sListId.isEmpty() )
431
22.9k
                    {
432
22.9k
                        Reference< XNamed > const xChapterNumNamed(
433
22.9k
                            m_xImpl->m_xChapterNumbering, UNO_QUERY);
434
22.9k
                        if ( xChapterNumNamed.is() )
435
22.9k
                        {
436
22.9k
                            m_xImpl->m_xTextListsHelper->KeepListAsProcessed(
437
22.9k
                                                    sListId,
438
22.9k
                                                    xChapterNumNamed->getName(),
439
22.9k
                                                    OUString() );
440
22.9k
                        }
441
22.9k
                    }
442
22.9k
                }
443
22.9k
            }
444
22.9k
        }
445
22.9k
    }
446
447
22.9k
    Reference< XStyleFamiliesSupplier > xFamiliesSupp( rModel, UNO_QUERY );
448
//  SAL_WARN_IF( !xFamiliesSupp.is(), "xmloff", "no chapter numbering supplier" ); for clipboard there may be documents without styles
449
450
22.9k
    if( xFamiliesSupp.is() )
451
22.9k
    {
452
22.9k
        Reference< XNameAccess > xFamilies(xFamiliesSupp->getStyleFamilies());
453
454
22.9k
        static constexpr OUString aParaStyles(u"ParagraphStyles"_ustr);
455
22.9k
        if( xFamilies->hasByName( aParaStyles ) )
456
22.9k
        {
457
22.9k
            m_xImpl->m_xParaStyles.set(xFamilies->getByName(aParaStyles),
458
22.9k
                UNO_QUERY);
459
22.9k
        }
460
461
22.9k
        static constexpr OUString aCharStyles(u"CharacterStyles"_ustr);
462
22.9k
        if( xFamilies->hasByName( aCharStyles ) )
463
22.9k
        {
464
22.9k
            m_xImpl->m_xTextStyles.set(xFamilies->getByName(aCharStyles),
465
22.9k
                UNO_QUERY);
466
22.9k
        }
467
468
22.9k
        static constexpr OUString aNumStyles(u"NumberingStyles"_ustr);
469
22.9k
        if( xFamilies->hasByName( aNumStyles ) )
470
22.9k
        {
471
22.9k
            m_xImpl->m_xNumStyles.set(xFamilies->getByName(aNumStyles),
472
22.9k
                UNO_QUERY);
473
22.9k
        }
474
475
22.9k
        static constexpr OUString aFrameStyles(u"FrameStyles"_ustr);
476
22.9k
        if( xFamilies->hasByName( aFrameStyles ) )
477
22.9k
        {
478
22.9k
            m_xImpl->m_xFrameStyles.set(xFamilies->getByName(aFrameStyles),
479
22.9k
                UNO_QUERY);
480
22.9k
        }
481
482
22.9k
        static constexpr OUString aPageStyles(u"PageStyles"_ustr);
483
22.9k
        if( xFamilies->hasByName( aPageStyles ) )
484
22.9k
        {
485
22.9k
            m_xImpl->m_xPageStyles.set(xFamilies->getByName(aPageStyles),
486
22.9k
                UNO_QUERY);
487
22.9k
        }
488
489
22.9k
        static constexpr OUString aCellStyles(u"CellStyles"_ustr);
490
22.9k
        if( xFamilies->hasByName( aCellStyles ) )
491
22.9k
        {
492
22.9k
            m_xImpl->m_xCellStyles.set(xFamilies->getByName(aCellStyles),
493
22.9k
                UNO_QUERY);
494
22.9k
        }
495
22.9k
    }
496
497
22.9k
    Reference < XTextFramesSupplier > xTFS( rModel, UNO_QUERY );
498
22.9k
    if( xTFS.is() )
499
22.9k
    {
500
22.9k
        m_xImpl->m_xTextFrames.set(xTFS->getTextFrames());
501
22.9k
    }
502
503
22.9k
    Reference < XTextGraphicObjectsSupplier > xTGOS( rModel, UNO_QUERY );
504
22.9k
    if( xTGOS.is() )
505
22.9k
    {
506
22.9k
        m_xImpl->m_xGraphics.set(xTGOS->getGraphicObjects());
507
22.9k
    }
508
509
22.9k
    Reference < XTextEmbeddedObjectsSupplier > xTEOS( rModel, UNO_QUERY );
510
22.9k
    if( xTEOS.is() )
511
22.9k
    {
512
22.9k
        m_xImpl->m_xObjects.set(xTEOS->getEmbeddedObjects());
513
22.9k
    }
514
515
22.9k
    XMLPropertySetMapper *pPropMapper =
516
22.9k
            new XMLTextPropertySetMapper( TextPropMap::PARA, false );
517
22.9k
    m_xImpl->m_xParaImpPrMap =
518
22.9k
        std::make_unique<XMLTextImportPropertyMapper>( pPropMapper, rImport );
519
520
22.9k
    pPropMapper = new XMLTextPropertySetMapper( TextPropMap::TEXT, false );
521
22.9k
    m_xImpl->m_xTextImpPrMap =
522
22.9k
        std::make_unique<XMLTextImportPropertyMapper>( pPropMapper, rImport );
523
524
22.9k
    pPropMapper = new XMLTextPropertySetMapper( TextPropMap::FRAME, false );
525
22.9k
    m_xImpl->m_xFrameImpPrMap =
526
22.9k
        std::make_unique<XMLTextImportPropertyMapper>( pPropMapper, rImport );
527
528
22.9k
    pPropMapper = new XMLTextPropertySetMapper( TextPropMap::SECTION, false );
529
22.9k
    m_xImpl->m_xSectionImpPrMap =
530
22.9k
        std::make_unique<XMLTextImportPropertyMapper>( pPropMapper, rImport );
531
532
22.9k
    pPropMapper = new XMLTextPropertySetMapper( TextPropMap::RUBY, false );
533
22.9k
    m_xImpl->m_xRubyImpPrMap =
534
22.9k
        std::make_unique<SvXMLImportPropertyMapper>( pPropMapper, rImport );
535
22.9k
}
536
537
XMLTextImportHelper::~XMLTextImportHelper()
538
22.9k
{
539
22.9k
}
540
541
void XMLTextImportHelper::dispose()
542
18.8k
{
543
18.8k
    if (m_xImpl->m_xAutoStyles)
544
3.49k
        m_xImpl->m_xAutoStyles->dispose();
545
18.8k
}
546
547
std::unique_ptr<SvXMLImportPropertyMapper> XMLTextImportHelper::CreateShapeExtPropMapper(SvXMLImport& rImport)
548
9.88k
{
549
9.88k
    XMLPropertySetMapper *pPropMapper =
550
9.88k
        new XMLTextPropertySetMapper( TextPropMap::FRAME, false );
551
9.88k
    return std::make_unique<XMLTextImportPropertyMapper>( pPropMapper, rImport );
552
9.88k
}
553
554
std::unique_ptr<SvXMLImportPropertyMapper> XMLTextImportHelper::CreateParaExtPropMapper(SvXMLImport& rImport)
555
9.88k
{
556
9.88k
    XMLPropertySetMapper *pPropMapper =
557
9.88k
        new XMLTextPropertySetMapper( TextPropMap::SHAPE_PARA, false );
558
9.88k
    return std::make_unique<XMLTextImportPropertyMapper>( pPropMapper, rImport );
559
9.88k
}
560
561
std::unique_ptr<SvXMLImportPropertyMapper> XMLTextImportHelper::CreateParaDefaultExtPropMapper(SvXMLImport& rImport)
562
9.88k
{
563
9.88k
    XMLPropertySetMapper* pPropMapper =
564
9.88k
        new XMLTextPropertySetMapper( TextPropMap::SHAPE_PARA, false );
565
9.88k
    std::unique_ptr<SvXMLImportPropertyMapper> pImportMapper(new XMLTextImportPropertyMapper( pPropMapper, rImport ));
566
567
9.88k
    pPropMapper =
568
9.88k
        new XMLTextPropertySetMapper( TextPropMap::TEXT_ADDITIONAL_DEFAULTS, false );
569
9.88k
    pImportMapper->ChainImportMapper( std::make_unique<XMLTextImportPropertyMapper>( pPropMapper, rImport ) );
570
571
9.88k
    return pImportMapper;
572
9.88k
}
573
574
std::unique_ptr<SvXMLImportPropertyMapper>
575
    XMLTextImportHelper::CreateTableDefaultExtPropMapper(
576
        SvXMLImport& rImport )
577
2.32k
{
578
2.32k
    XMLPropertySetMapper *pPropMapper =
579
2.32k
        new XMLTextPropertySetMapper( TextPropMap::TABLE_DEFAULTS, false );
580
2.32k
    return std::make_unique<SvXMLImportPropertyMapper>( pPropMapper, rImport );
581
2.32k
}
582
583
std::unique_ptr<SvXMLImportPropertyMapper>
584
    XMLTextImportHelper::CreateTableRowDefaultExtPropMapper(
585
        SvXMLImport& rImport )
586
2.33k
{
587
2.33k
    XMLPropertySetMapper *pPropMapper =
588
2.33k
        new XMLTextPropertySetMapper( TextPropMap::TABLE_ROW_DEFAULTS, false );
589
2.33k
    return std::make_unique<SvXMLImportPropertyMapper>( pPropMapper, rImport );
590
2.33k
}
591
592
std::unique_ptr<SvXMLImportPropertyMapper>
593
    XMLTextImportHelper::CreateTableCellExtPropMapper(
594
        SvXMLImport& rImport )
595
7.61k
{
596
7.61k
    XMLPropertySetMapper *pPropMapper =
597
7.61k
        new XMLTextPropertySetMapper( TextPropMap::CELL, false );
598
7.61k
    return std::make_unique<XMLTextImportPropertyMapper>( pPropMapper, rImport );
599
7.61k
}
600
601
std::unique_ptr<SvXMLImportPropertyMapper>
602
XMLTextImportHelper::CreateDrawingPageExtPropMapper(SvXMLImport& rImport)
603
294
{
604
294
    rtl::Reference<XMLPropertyHandlerFactory> const pFactory(new XMLPageMasterPropHdlFactory);
605
294
    XMLPropertySetMapper *const pPropMapper(
606
294
        new XMLPropertySetMapper(g_XMLPageMasterDrawingPageStyleMap, pFactory, false));
607
294
    return std::make_unique<SvXMLImportPropertyMapper>(pPropMapper, rImport);
608
294
}
609
610
void XMLTextImportHelper::SetCursor( const Reference < XTextCursor > & rCursor )
611
99.9k
{
612
99.9k
    m_xImpl->m_xCursor.set(rCursor);
613
99.9k
    m_xImpl->m_xText.set(rCursor->getText());
614
99.9k
    m_xImpl->m_xCursorAsRange = rCursor;
615
99.9k
}
616
617
void XMLTextImportHelper::ResetCursor()
618
6.48k
{
619
6.48k
    m_xImpl->m_xCursor.clear();
620
6.48k
    m_xImpl->m_xText.clear();
621
6.48k
    m_xImpl->m_xCursorAsRange.clear();
622
6.48k
}
623
624
625
bool XMLTextImportHelper::HasFrameByName( const OUString& rName ) const
626
2.34M
{
627
2.34M
    return (m_xImpl->m_xTextFrames.is() &&
628
2.34M
            m_xImpl->m_xTextFrames->hasByName(rName))
629
2.27M
        || (m_xImpl->m_xGraphics.is() &&
630
2.27M
            m_xImpl->m_xGraphics->hasByName(rName))
631
69.4k
        || (m_xImpl->m_xObjects.is() &&
632
69.4k
            m_xImpl->m_xObjects->hasByName(rName));
633
2.34M
}
634
635
bool XMLTextImportHelper::IsDuplicateFrame(const OUString& sName, sal_Int32 nX, sal_Int32 nY, sal_Int32 nWidth, sal_Int32 nHeight) const
636
10.2k
{
637
10.2k
    if (HasFrameByName(sName))
638
6.43k
    {
639
6.43k
        uno::Reference<beans::XPropertySet> xOtherFrame;
640
6.43k
        if(m_xImpl->m_xTextFrames.is() && m_xImpl->m_xTextFrames->hasByName(sName))
641
6.26k
            xOtherFrame.set(m_xImpl->m_xTextFrames->getByName(sName), uno::UNO_QUERY);
642
162
        else if(m_xImpl->m_xGraphics.is() && m_xImpl->m_xGraphics->hasByName(sName))
643
159
            xOtherFrame.set(m_xImpl->m_xGraphics->getByName(sName), uno::UNO_QUERY);
644
3
        else if (m_xImpl->m_xObjects.is() && m_xImpl->m_xObjects->hasByName(sName))
645
3
            xOtherFrame.set(m_xImpl->m_xObjects->getByName(sName), uno::UNO_QUERY);
646
647
6.43k
        Reference< XPropertySetInfo > xPropSetInfo = xOtherFrame->getPropertySetInfo();
648
6.43k
        if(xPropSetInfo->hasPropertyByName(u"Width"_ustr))
649
6.43k
        {
650
6.43k
            sal_Int32 nOtherWidth = 0;
651
6.43k
            xOtherFrame->getPropertyValue(u"Width"_ustr) >>= nOtherWidth;
652
6.43k
            if(nWidth != nOtherWidth)
653
6.25k
                return false;
654
6.43k
        }
655
656
179
        if (xPropSetInfo->hasPropertyByName(u"Height"_ustr))
657
179
        {
658
179
            sal_Int32 nOtherHeight = 0;
659
179
            xOtherFrame->getPropertyValue(u"Height"_ustr) >>= nOtherHeight;
660
179
            if (nHeight != nOtherHeight)
661
90
                return false;
662
179
        }
663
664
89
        if (xPropSetInfo->hasPropertyByName(u"HoriOrientPosition"_ustr))
665
89
        {
666
89
            sal_Int32 nOtherX = 0;
667
89
            xOtherFrame->getPropertyValue(u"HoriOrientPosition"_ustr) >>= nOtherX;
668
89
            if (nX != nOtherX)
669
0
                return false;
670
89
        }
671
672
89
        if (xPropSetInfo->hasPropertyByName(u"VertOrientPosition"_ustr))
673
89
        {
674
89
            sal_Int32 nOtherY = 0;
675
89
            xOtherFrame->getPropertyValue(u"VertOrientPosition"_ustr) >>= nOtherY;
676
89
            if (nY != nOtherY)
677
0
                return false;
678
89
        }
679
680
        // In some case, position is not defined for frames, so check whether the two frames follow each other (are anchored to the same position)
681
89
        return m_xImpl->msLastImportedFrameName == sName;
682
89
    }
683
3.80k
    return false;
684
10.2k
}
685
686
void XMLTextImportHelper::StoreLastImportedFrameName(const OUString& rName)
687
24.3k
{
688
24.3k
    m_xImpl->msLastImportedFrameName = rName;
689
24.3k
}
690
691
void XMLTextImportHelper::ClearLastImportedTextFrameName()
692
345k
{
693
345k
    m_xImpl->msLastImportedFrameName.clear();
694
345k
}
695
696
void XMLTextImportHelper::InsertString( const OUString& rChars )
697
9.33k
{
698
9.33k
    assert(m_xImpl->m_xText.is());
699
9.33k
    assert(m_xImpl->m_xCursorAsRange.is());
700
9.33k
    if (m_xImpl->m_xText.is())
701
9.33k
    {
702
9.33k
        m_xImpl->m_xText->insertString(m_xImpl->m_xCursorAsRange,
703
9.33k
            rChars, false);
704
9.33k
    }
705
9.33k
}
706
707
void XMLTextImportHelper::InsertString( std::u16string_view rChars,
708
                                        bool& rIgnoreLeadingSpace )
709
85.8k
{
710
85.8k
    assert(m_xImpl->m_xText.is());
711
85.8k
    assert(m_xImpl->m_xCursorAsRange.is());
712
85.8k
    if (!m_xImpl->m_xText.is())
713
0
        return;
714
715
85.8k
    sal_Int32 nLen = rChars.size();
716
85.8k
    OUStringBuffer sChars( nLen );
717
718
32.0M
    for( sal_Int32 i=0; i < nLen; i++ )
719
31.9M
    {
720
31.9M
        sal_Unicode c = rChars[i];
721
31.9M
        switch( c )
722
31.9M
        {
723
1.24M
            case 0x20:
724
1.26M
            case 0x09:
725
1.35M
            case 0x0a:
726
1.35M
            case 0x0d:
727
1.35M
                if( !rIgnoreLeadingSpace )
728
984k
                    sChars.append( u' ' );
729
1.35M
                rIgnoreLeadingSpace = true;
730
1.35M
                break;
731
30.5M
            default:
732
30.5M
                rIgnoreLeadingSpace = false;
733
30.5M
                sChars.append( c );
734
30.5M
                break;
735
31.9M
        }
736
31.9M
    }
737
85.8k
    m_xImpl->m_xText->insertString(m_xImpl->m_xCursorAsRange,
738
85.8k
                                   sChars.makeStringAndClear(), false);
739
85.8k
}
740
741
void XMLTextImportHelper::InsertControlCharacter( sal_Int16 nControl )
742
230k
{
743
230k
    assert(m_xImpl->m_xText.is());
744
230k
    assert(m_xImpl->m_xCursorAsRange.is());
745
230k
    if (m_xImpl->m_xText.is())
746
230k
    {
747
230k
        m_xImpl->m_xText->insertControlCharacter(
748
230k
            m_xImpl->m_xCursorAsRange, nControl, false);
749
230k
    }
750
230k
}
751
752
void XMLTextImportHelper::InsertTextContent(
753
    Reference < XTextContent > const & xContent )
754
88.1k
{
755
88.1k
    assert(m_xImpl->m_xText.is());
756
88.1k
    assert(m_xImpl->m_xCursorAsRange.is());
757
88.1k
    if (m_xImpl->m_xText.is())
758
88.1k
    {
759
        // note: this may throw IllegalArgumentException and callers handle it
760
88.1k
        m_xImpl->m_xText->insertTextContent( m_xImpl->m_xCursorAsRange, xContent, false);
761
88.1k
    }
762
88.1k
}
763
764
void XMLTextImportHelper::DeleteParagraph(bool dontCorrectBookmarks)
765
32.3k
{
766
32.3k
    assert(m_xImpl->m_xText.is());
767
32.3k
    assert(m_xImpl->m_xCursor.is());
768
32.3k
    assert(m_xImpl->m_xCursorAsRange.is());
769
770
32.3k
    bool bDelete = true;
771
32.3k
    Reference < XEnumerationAccess > const xEnumAccess(
772
32.3k
        m_xImpl->m_xCursor, UNO_QUERY);
773
32.3k
    if( xEnumAccess.is() )
774
32.3k
    {
775
32.3k
        Reference < XEnumeration > xEnum(xEnumAccess->createEnumeration());
776
32.3k
        SAL_WARN_IF(!xEnum->hasMoreElements(), "xmloff.text",
777
32.3k
                "empty text enumeration");
778
32.3k
        if( xEnum->hasMoreElements() )
779
32.3k
        {
780
32.3k
            Reference < XComponent > xComp( xEnum->nextElement(), UNO_QUERY );
781
32.3k
            assert(xComp.is());
782
32.3k
            if( xComp.is() )
783
32.3k
            {
784
32.3k
                if (dontCorrectBookmarks)
785
6.28k
                {
786
6.28k
                    try
787
6.28k
                    {
788
                        // See SwXParagraph::setPropertyValue
789
6.28k
                        if (auto xProps = xComp.query<beans::XPropertySet>())
790
6.28k
                            xProps->setPropertyValue(u"DeleteWithoutCorrection"_ustr, {});
791
6.28k
                    }
792
6.28k
                    catch (const beans::UnknownPropertyException&)
793
6.28k
                    {
794
0
                    }
795
6.28k
                }
796
32.3k
                xComp->dispose();
797
32.3k
                bDelete = false;
798
32.3k
            }
799
32.3k
        }
800
32.3k
    }
801
32.3k
    if( bDelete )
802
0
    {
803
0
        if (m_xImpl->m_xCursor->goLeft( 1, true ))
804
0
        {
805
0
            m_xImpl->m_xText->insertString(m_xImpl->m_xCursorAsRange,
806
0
                                           u""_ustr, true);
807
0
        }
808
0
    }
809
32.3k
}
810
811
OUString XMLTextImportHelper::ConvertStarFonts( const OUString& rChars,
812
                                                const OUString& rStyleName,
813
                                                sal_uInt8& rFlags,
814
                                                bool bPara,
815
                                                SvXMLImport& rImport ) const
816
80.5k
{
817
80.5k
    OUStringBuffer sChars( rChars );
818
80.5k
    bool bConverted = false;
819
28.7M
    for( sal_Int32 j=0; j<rChars.getLength(); j++ )
820
28.6M
    {
821
28.6M
        sal_Unicode c = rChars[j];
822
28.6M
        if( c >= 0xf000 && c <= 0xf0ff )
823
69
        {
824
69
            if( (rFlags & CONV_STAR_FONT_FLAGS_VALID) == 0 )
825
5
            {
826
5
                XMLTextStyleContext *pStyle = nullptr;
827
5
                XmlStyleFamily nFamily = bPara ? XmlStyleFamily::TEXT_PARAGRAPH
828
5
                                               : XmlStyleFamily::TEXT_TEXT;
829
5
                if (!rStyleName.isEmpty() && m_xImpl->m_xAutoStyles.is())
830
0
                {
831
0
                    const SvXMLStyleContext* pTempStyle =
832
0
                        m_xImpl->m_xAutoStyles->
833
0
                                FindStyleChildContext( nFamily, rStyleName,
834
0
                                                       true );
835
0
                    pStyle = const_cast<XMLTextStyleContext*>( dynamic_cast< const XMLTextStyleContext* >(pTempStyle));
836
0
                }
837
838
5
                if( pStyle )
839
0
                {
840
0
                    sal_Int32 nCount = pStyle->GetProperties_().size();
841
0
                    if( nCount )
842
0
                    {
843
0
                        SvXMLImportPropertyMapper* pImpPrMap =
844
0
                            m_xImpl->m_xAutoStyles->GetImportPropertyMapper(nFamily);
845
0
                        if( pImpPrMap )
846
0
                        {
847
0
                            rtl::Reference<XMLPropertySetMapper> rPropMapper =
848
0
                                pImpPrMap->getPropertySetMapper();
849
0
                            for( sal_Int32 i=0; i < nCount; i++ )
850
0
                            {
851
0
                                const XMLPropertyState& rProp = pStyle->GetProperties_()[i];
852
0
                                sal_Int32 nIdx = rProp.mnIndex;
853
0
                                sal_uInt32 nContextId = rPropMapper->GetEntryContextId(nIdx);
854
0
                                if( CTF_FONTFAMILYNAME == nContextId )
855
0
                                {
856
0
                                    rFlags &= ~(CONV_FROM_STAR_BATS|CONV_FROM_STAR_MATH);
857
0
                                    OUString sFontName;
858
0
                                    rProp.maValue >>= sFontName;
859
0
                                    if( sFontName.equalsIgnoreAsciiCase( "StarBats"  ) )
860
0
                                        rFlags |= CONV_FROM_STAR_BATS;
861
0
                                    else if( sFontName.equalsIgnoreAsciiCase( "StarMath" ) )
862
0
                                        rFlags |= CONV_FROM_STAR_MATH;
863
0
                                    break;
864
0
                                }
865
0
                            }
866
0
                        }
867
0
                    }
868
869
0
                }
870
871
5
                rFlags |= CONV_STAR_FONT_FLAGS_VALID;
872
5
            }
873
69
            if( (rFlags & CONV_FROM_STAR_BATS ) != 0 )
874
0
            {
875
0
                sChars[j] = rImport.ConvStarBatsCharToStarSymbol( c );
876
0
                bConverted = true;
877
0
            }
878
69
            else if( (rFlags & CONV_FROM_STAR_MATH ) != 0 )
879
0
            {
880
0
                sChars[j] = rImport.ConvStarMathCharToStarSymbol( c );
881
0
                bConverted = true;
882
0
            }
883
69
        }
884
28.6M
    }
885
886
80.5k
    return bConverted ? sChars.makeStringAndClear() : rChars;
887
80.5k
}
888
889
/* Helper method to determine, if a paragraph style has a list style (inclusive
890
   an empty one) inherits a list style (inclusive an empty one) from one of its parents (#i69629#)
891
*/
892
/* Apply special case, that found list style equals the chapter numbering, also
893
   to the found list styles of the parent styles. (#i73973#)
894
*/
895
static bool lcl_HasListStyle( const OUString& sStyleName,
896
                              const Reference < XNameContainer >& xParaStyles,
897
                              SvXMLImport const & rImport,
898
                              const OUString& sNumberingStyleName,
899
                              std::u16string_view sOutlineStyleName )
900
140k
{
901
140k
    bool bRet( false );
902
903
140k
    if ( !xParaStyles->hasByName( sStyleName ) )
904
0
    {
905
        // error case
906
0
        return true;
907
0
    }
908
909
140k
    Reference< XPropertyState > xPropState( xParaStyles->getByName( sStyleName ),
910
140k
                                            UNO_QUERY );
911
140k
    if ( !xPropState.is() )
912
0
    {
913
        // error case
914
0
        return false;
915
0
    }
916
917
140k
    if ( xPropState->getPropertyState( sNumberingStyleName ) == PropertyState_DIRECT_VALUE )
918
139k
    {
919
        // list style found
920
139k
        bRet = true;
921
        // special case: the set list style equals the chapter numbering
922
139k
        Reference< XPropertySet > xPropSet( xPropState, UNO_QUERY );
923
139k
        if ( xPropSet.is() )
924
139k
        {
925
139k
            OUString sListStyle;
926
139k
            xPropSet->getPropertyValue( sNumberingStyleName ) >>= sListStyle;
927
139k
            if ( !sListStyle.isEmpty() &&
928
139k
                 sListStyle == sOutlineStyleName )
929
7.05k
            {
930
7.05k
                bRet = false;
931
7.05k
            }
932
139k
        }
933
139k
    }
934
1.08k
    else
935
1.08k
    {
936
        // Tools.Outline settings lost on Save (#i77708#)
937
1.08k
        sal_Int32 nUPD( 0 );
938
1.08k
        sal_Int32 nBuild( 0 );
939
        // Don't use UPD for versioning: xmloff/source/text/txtstyli.cxx and txtimp.cxx (#i86058#)
940
1.08k
        const bool bBuildIdFound = rImport.getBuildIds( nUPD, nBuild );
941
        // search list style at parent
942
1.08k
        Reference<XStyle> xStyle( xPropState, UNO_QUERY );
943
2.74k
        while ( xStyle.is() )
944
2.74k
        {
945
2.74k
            OUString aParentStyle( xStyle->getParentStyle() );
946
2.74k
            if ( !aParentStyle.isEmpty() )
947
1.66k
            {
948
1.66k
                aParentStyle =
949
1.66k
                    rImport.GetStyleDisplayName( XmlStyleFamily::TEXT_PARAGRAPH,
950
1.66k
                                                 aParentStyle );
951
1.66k
            }
952
2.74k
            if ( aParentStyle.isEmpty() || !xParaStyles->hasByName( aParentStyle ) )
953
1.08k
            {
954
                // no list style found
955
1.08k
                break;
956
1.08k
            }
957
1.66k
            else
958
1.66k
            {
959
1.66k
                xPropState.set( xParaStyles->getByName( aParentStyle ),
960
1.66k
                                UNO_QUERY );
961
1.66k
                if ( !xPropState.is() )
962
0
                {
963
                    // error case
964
0
                    return true;
965
0
                }
966
1.66k
                if ( xPropState->getPropertyState( sNumberingStyleName ) == PropertyState_DIRECT_VALUE )
967
0
                {
968
                    // list style found
969
0
                    bRet = true;
970
                    // Special case: the found list style equals the chapter numbering (#i73973#)
971
0
                    Reference< XPropertySet > xPropSet( xPropState, UNO_QUERY );
972
0
                    if ( xPropSet.is() )
973
0
                    {
974
0
                        OUString sListStyle;
975
0
                        xPropSet->getPropertyValue( sNumberingStyleName ) >>= sListStyle;
976
0
                        if ( !sListStyle.isEmpty() &&
977
0
                             sListStyle == sOutlineStyleName )
978
0
                        {
979
0
                            bRet = false;
980
0
                        }
981
                        // Special handling for text documents from OOo version prior OOo 2.4 (#i77708#)
982
                        /* Check explicitly on certain versions and on import of
983
                           text documents in OpenOffice.org file format (#i86058#)
984
                        */
985
0
                        else if ( sListStyle.isEmpty() &&
986
0
                                  ( rImport.IsTextDocInOOoFileFormat() ||
987
0
                                    ( bBuildIdFound &&
988
0
                                      ( ( nUPD == 641 ) || ( nUPD == 645 ) || // prior OOo 2.0
989
0
                                        ( nUPD == 680 && nBuild <= 9238 ) ) ) ) ) // OOo 2.0 - OOo 2.3.1
990
0
                        {
991
0
                            bRet = false;
992
0
                        }
993
0
                    }
994
0
                    break;
995
0
                }
996
1.66k
                else
997
1.66k
                {
998
                    // search list style at parent
999
1.66k
                    Reference<XStyle> xParentStyle(xPropState, UNO_QUERY);
1000
1.66k
                    if (xStyle == xParentStyle)
1001
0
                    {
1002
                        // error case
1003
0
                        return true;
1004
0
                    }
1005
1.66k
                    xStyle = std::move(xParentStyle);
1006
1.66k
                }
1007
1.66k
            }
1008
2.74k
        }
1009
1.08k
    }
1010
1011
140k
    return bRet;
1012
140k
}
1013
1014
OUString XMLTextImportHelper::SetStyleAndAttrs(
1015
        const SvXMLImport & rImport,
1016
        const Reference < XTextCursor >& rCursor,
1017
        const OUString& rStyleName,
1018
        bool bPara,
1019
        bool bOutlineLevelAttrFound,
1020
        sal_Int8 nOutlineLevel,
1021
        // Numberings/Bullets in table not visible after save/reload (#i80724#)
1022
        bool bSetListAttrs,
1023
        bool bOutlineContentVisible)
1024
238k
{
1025
238k
    static constexpr OUString s_NumberingRules = u"NumberingRules"_ustr;
1026
238k
    static constexpr OUString s_NumberingIsNumber = u"NumberingIsNumber"_ustr;
1027
238k
    static constexpr OUString s_NumberingLevel = u"NumberingLevel"_ustr;
1028
238k
    static constexpr OUString s_ParaIsNumberingRestart = u"ParaIsNumberingRestart"_ustr;
1029
238k
    static constexpr OUString s_NumberingStartValue = u"NumberingStartValue"_ustr;
1030
238k
    static constexpr OUString s_PropNameListId = u"ListId"_ustr;
1031
238k
    static constexpr OUString s_PageDescName = u"PageDescName"_ustr;
1032
238k
    static constexpr OUString s_OutlineLevel = u"OutlineLevel"_ustr;
1033
1034
238k
    const XmlStyleFamily nFamily = bPara ? XmlStyleFamily::TEXT_PARAGRAPH
1035
238k
                                         : XmlStyleFamily::TEXT_TEXT;
1036
238k
    XMLTextStyleContext *pStyle = nullptr;
1037
238k
    OUString sStyleName( rStyleName );
1038
238k
    if (!sStyleName.isEmpty() && m_xImpl->m_xAutoStyles.is())
1039
131k
    {
1040
131k
        const SvXMLStyleContext* pTempStyle =
1041
131k
            m_xImpl->m_xAutoStyles->FindStyleChildContext( nFamily, sStyleName, true );
1042
131k
        pStyle = const_cast<XMLTextStyleContext*>(dynamic_cast< const XMLTextStyleContext* >(pTempStyle));
1043
131k
    }
1044
238k
    if( pStyle )
1045
25.2k
        sStyleName = pStyle->GetParentName();
1046
1047
238k
    Reference < XPropertySet > xPropSet( rCursor, UNO_QUERY );
1048
238k
    Reference< XPropertySetInfo > xPropSetInfo(
1049
238k
        xPropSet->getPropertySetInfo());
1050
1051
    // style
1052
238k
    if( !sStyleName.isEmpty() )
1053
208k
    {
1054
208k
        sStyleName = rImport.GetStyleDisplayName( nFamily, sStyleName );
1055
208k
        const OUString rPropName = bPara ? u"ParaStyleName"_ustr : u"CharStyleName"_ustr;
1056
208k
        const Reference < XNameContainer > & rStyles = bPara
1057
208k
            ? m_xImpl->m_xParaStyles
1058
208k
            : m_xImpl->m_xTextStyles;
1059
208k
        if( rStyles.is() &&
1060
208k
            xPropSetInfo->hasPropertyByName( rPropName ) &&
1061
170k
            rStyles->hasByName( sStyleName ) )
1062
154k
        {
1063
154k
            xPropSet->setPropertyValue( rPropName, Any(sStyleName) );
1064
154k
        }
1065
54.2k
        else
1066
54.2k
            sStyleName.clear();
1067
208k
    }
1068
1069
    /* The outline level needs to be only applied as list level, if the heading
1070
       is not inside a list and if it by default applies the outline style. (#i70748#)
1071
    */
1072
238k
    bool bApplyOutlineLevelAsListLevel( false );
1073
    // Numberings/Bullets in table not visible after save/reload (#i80724#)
1074
238k
    if (bSetListAttrs && bPara
1075
228k
        && xPropSetInfo->hasPropertyByName( s_NumberingRules))
1076
228k
    {
1077
        // Set numbering rules
1078
228k
        Reference< XIndexReplace > const xNumRules(
1079
228k
                xPropSet->getPropertyValue(s_NumberingRules), UNO_QUERY);
1080
1081
228k
        XMLTextListBlockContext * pListBlock(nullptr);
1082
228k
        XMLTextListItemContext  * pListItem(nullptr);
1083
228k
        XMLNumberedParaContext  * pNumberedParagraph(nullptr);
1084
228k
        GetTextListHelper().ListContextTop(
1085
228k
            pListBlock, pListItem, pNumberedParagraph);
1086
1087
228k
        assert(!(pListBlock && pNumberedParagraph) && "XMLTextImportHelper::"
1088
228k
            "SetStyleAndAttrs: both list and numbered-paragraph???");
1089
1090
228k
        Reference < XIndexReplace > xNewNumRules;
1091
228k
        sal_Int8 nLevel(-1);
1092
228k
        OUString sListId;
1093
228k
        sal_Int16 nStartValue(-1);
1094
228k
        bool bNumberingIsNumber(true);
1095
        // Assure that list style of automatic paragraph style is applied at paragraph. (#i101349#)
1096
228k
        bool bApplyNumRules(pStyle && pStyle->IsListStyleSet());
1097
1098
228k
        if (pListBlock) {
1099
1100
0
            if (!pListItem) {
1101
0
                bNumberingIsNumber = false; // list-header
1102
0
            }
1103
1104
            // consider text:style-override property of <text:list-item>
1105
0
            xNewNumRules.set(
1106
0
                (pListItem != nullptr && pListItem->HasNumRulesOverride())
1107
0
                    ? pListItem->GetNumRulesOverride()
1108
0
                    : pListBlock->GetNumRules() );
1109
0
            nLevel = static_cast<sal_Int8>(pListBlock->GetLevel());
1110
1111
0
            if ( pListItem && pListItem->HasStartValue() ) {
1112
0
               nStartValue = pListItem->GetStartValue();
1113
0
            }
1114
1115
            // Inconsistent behavior regarding lists (#i92811#)
1116
0
            sListId = m_xImpl->m_xTextListsHelper->GetListIdForListBlock(
1117
0
                            *pListBlock);
1118
0
        }
1119
228k
        else if (pNumberedParagraph)
1120
42.1k
        {
1121
42.1k
            xNewNumRules.set(pNumberedParagraph->GetNumRules());
1122
42.1k
            nLevel = static_cast<sal_Int8>(pNumberedParagraph->GetLevel());
1123
42.1k
            sListId = pNumberedParagraph->GetListId();
1124
42.1k
            nStartValue = pNumberedParagraph->GetStartValue();
1125
42.1k
        }
1126
1127
1128
228k
        if (pListBlock || pNumberedParagraph)
1129
42.1k
        {
1130
42.1k
            if (!bApplyNumRules)
1131
42.1k
            {
1132
42.1k
                bool bSameNumRules = xNewNumRules == xNumRules;
1133
42.1k
                if( !bSameNumRules && xNewNumRules.is() && xNumRules.is() )
1134
41.7k
                {
1135
                    // If the interface pointers are different, then this does
1136
                    // not mean that the num rules are different. Further tests
1137
                    // are required then. However, if only one num rule is
1138
                    // set, no tests are required of course.
1139
41.7k
                    Reference< XNamed > xNewNamed( xNewNumRules, UNO_QUERY );
1140
41.7k
                    Reference< XNamed > xNamed( xNumRules, UNO_QUERY );
1141
41.7k
                    if( xNewNamed.is() && xNamed.is() )
1142
24.4k
                    {
1143
24.4k
                        bSameNumRules = xNewNamed->getName() == xNamed->getName();
1144
24.4k
                    }
1145
17.3k
                    else
1146
17.3k
                    {
1147
17.3k
                        Reference< XAnyCompare > xNumRuleCompare( xNumRules, UNO_QUERY );
1148
17.3k
                        if( xNumRuleCompare.is() )
1149
17.3k
                        {
1150
17.3k
                            bSameNumRules = (xNumRuleCompare->compare( Any(xNumRules), Any(xNewNumRules) ) == 0);
1151
17.3k
                        }
1152
17.3k
                    }
1153
41.7k
                }
1154
42.1k
                bApplyNumRules = !bSameNumRules;
1155
42.1k
            }
1156
1157
42.1k
            if ( bApplyNumRules )
1158
42.1k
            {
1159
                // #102607# This may except when xNewNumRules contains
1160
                // a Writer-NumRule-Implementation bug gets applied to
1161
                // a shape. Since this may occur inside a document
1162
                // (e.g. when edited), this must be handled
1163
                // gracefully.
1164
42.1k
                try
1165
42.1k
                {
1166
42.1k
                    xPropSet->setPropertyValue(
1167
42.1k
                        s_NumberingRules, Any(xNewNumRules) );
1168
42.1k
                }
1169
42.1k
                catch(const Exception&)
1170
42.1k
                {
1171
0
                    ; // I would really like to use a warning here,
1172
                      // but I can't access the XMLErrorHandler from
1173
                      // here.
1174
0
                }
1175
42.1k
            }
1176
1177
42.1k
            if (!bNumberingIsNumber &&
1178
0
                xPropSetInfo->hasPropertyByName(s_NumberingIsNumber))
1179
0
            {
1180
0
                xPropSet->setPropertyValue(s_NumberingIsNumber, Any(false));
1181
0
            }
1182
1183
42.1k
            xPropSet->setPropertyValue( s_NumberingLevel, Any(nLevel) );
1184
1185
42.1k
            if( pListBlock && pListBlock->IsRestartNumbering() )
1186
0
            {
1187
                // TODO: property missing
1188
0
                if (xPropSetInfo->hasPropertyByName(s_ParaIsNumberingRestart))
1189
0
                {
1190
0
                    xPropSet->setPropertyValue(s_ParaIsNumberingRestart,
1191
0
                                               Any(true) );
1192
0
                }
1193
0
                pListBlock->ResetRestartNumbering();
1194
0
            }
1195
1196
42.1k
            if ( 0 <= nStartValue &&
1197
0
                xPropSetInfo->hasPropertyByName(s_NumberingStartValue))
1198
0
            {
1199
0
                xPropSet->setPropertyValue(s_NumberingStartValue,
1200
0
                                           Any(nStartValue));
1201
0
            }
1202
1203
42.1k
            if (xPropSetInfo->hasPropertyByName(s_PropNameListId))
1204
24.7k
            {
1205
24.7k
                if (!sListId.isEmpty()) {
1206
24.7k
                    xPropSet->setPropertyValue(s_PropNameListId,
1207
24.7k
                        Any(sListId) );
1208
24.7k
                }
1209
24.7k
            }
1210
1211
42.1k
            GetTextListHelper().SetListItem( nullptr );
1212
42.1k
        }
1213
186k
        else
1214
186k
        {
1215
            /* If the paragraph is not in a list but its style, remove it from
1216
               the list. Do not remove it, if the list of the style is
1217
               the chapter numbering rule.
1218
            */
1219
186k
            if( xNumRules.is() )
1220
142k
            {
1221
142k
                bool bRemove( true );
1222
                // Special handling for document from OOo 2.x (#i70748#)
1223
142k
                sal_Int32 nUPD( 0 );
1224
142k
                sal_Int32 nBuild( 0 );
1225
142k
                const bool bBuildIdFound = rImport.getBuildIds( nUPD, nBuild );
1226
142k
                if ( ( bBuildIdFound && nUPD == 680 ) ||
1227
142k
                     !pStyle || !pStyle->IsListStyleSet() )
1228
142k
                {
1229
142k
                    if (m_xImpl->m_xChapterNumbering.is())
1230
142k
                    {
1231
142k
                        Reference< XNamed > xNumNamed( xNumRules, UNO_QUERY );
1232
142k
                        Reference< XNamed > const xChapterNumNamed (
1233
142k
                            m_xImpl->m_xChapterNumbering, UNO_QUERY);
1234
142k
                        if ( xNumNamed.is() && xChapterNumNamed.is() &&
1235
105k
                             xNumNamed->getName() == xChapterNumNamed->getName() )
1236
105k
                        {
1237
105k
                            bRemove = false;
1238
                            // RFE: inserting headings into text documents (#i70748#)
1239
105k
                            bApplyOutlineLevelAsListLevel = true;
1240
105k
                        }
1241
142k
                    }
1242
142k
                }
1243
0
                else
1244
0
                {
1245
0
                    SAL_INFO_IF(!pStyle->GetListStyle().isEmpty(),
1246
0
                        "xmloff.text",
1247
0
                        "automatic paragraph style with list style name, but paragraph not in list???");
1248
0
                }
1249
142k
                if ( bRemove )
1250
36.4k
                {
1251
36.4k
                    xPropSet->setPropertyValue( s_NumberingRules, Any() );
1252
36.4k
                }
1253
142k
            }
1254
186k
        }
1255
228k
    }
1256
1257
    // hard paragraph properties
1258
238k
    if( pStyle )
1259
25.2k
    {
1260
25.2k
        pStyle->FillPropertySet( xPropSet );
1261
25.2k
        if( bPara && pStyle->HasMasterPageName() &&
1262
260
            xPropSetInfo->hasPropertyByName(s_PageDescName))
1263
260
        {
1264
260
            OUString sDisplayName(
1265
260
                rImport.GetStyleDisplayName(
1266
260
                                XmlStyleFamily::MASTER_PAGE,
1267
260
                                pStyle->GetMasterPageName()) );
1268
260
            if( sDisplayName.isEmpty() ||
1269
222
                (m_xImpl->m_xPageStyles.is() &&
1270
222
                 m_xImpl->m_xPageStyles->hasByName( sDisplayName)))
1271
259
            {
1272
259
                xPropSet->setPropertyValue(s_PageDescName,
1273
259
                        Any(sDisplayName));
1274
259
            }
1275
260
        }
1276
25.2k
        if( bPara && !pStyle->GetDropCapStyleName().isEmpty() &&
1277
0
            m_xImpl->m_xTextStyles.is())
1278
0
        {
1279
0
            OUString sDisplayName(
1280
0
                rImport.GetStyleDisplayName(
1281
0
                                XmlStyleFamily::TEXT_TEXT,
1282
0
                                pStyle->GetDropCapStyleName()) );
1283
0
            if (m_xImpl->m_xTextStyles->hasByName(sDisplayName) &&
1284
0
                xPropSetInfo->hasPropertyByName(u"DropCapCharStyleName"_ustr))
1285
0
            {
1286
0
                xPropSet->setPropertyValue(u"DropCapCharStyleName"_ustr, Any(sDisplayName));
1287
0
            }
1288
0
        }
1289
1290
        // combined characters special treatment
1291
25.2k
        if (!bPara && pStyle->HasCombinedCharactersLetter())
1292
0
        {
1293
            // insert combined characters text field
1294
0
            if (m_xImpl->m_xServiceFactory.is())
1295
0
            {
1296
0
                uno::Reference<beans::XPropertySet> const xTmp(
1297
0
                    m_xImpl->m_xServiceFactory->createInstance(
1298
0
                        u"com.sun.star.text.TextField.CombinedCharacters"_ustr), UNO_QUERY);
1299
0
                if( xTmp.is() )
1300
0
                {
1301
                    // maximum allowed length of combined characters field
1302
0
                    constexpr auto MAX_COMBINED_CHARACTERS = 6;
1303
1304
                    // fix cursor if larger than possible for
1305
                    // combined characters field
1306
0
                    if (rCursor->getString().getLength() >
1307
0
                            MAX_COMBINED_CHARACTERS)
1308
0
                    {
1309
0
                        rCursor->gotoRange(rCursor->getStart(), false);
1310
0
                        rCursor->goRight(MAX_COMBINED_CHARACTERS, true);
1311
0
                    }
1312
1313
                    // set field value (the combined character string)
1314
0
                    xTmp->setPropertyValue(u"Content"_ustr,
1315
0
                        Any(rCursor->getString()));
1316
1317
                    // insert the field over it's original text
1318
0
                    Reference<XTextContent> xTextContent(xTmp, UNO_QUERY);
1319
0
                    if (m_xImpl->m_xText.is() && rCursor.is())
1320
0
                    {
1321
                        // #i107225# the combined characters need to be inserted first
1322
                        // the selected text has to be removed afterwards
1323
0
                        m_xImpl->m_xText->insertTextContent( rCursor->getStart(), xTextContent, true );
1324
1325
0
                        if( !rCursor->getString().isEmpty() )
1326
0
                        {
1327
0
                            try
1328
0
                            {
1329
0
                                uno::Reference< text::XTextCursor > xCrsr = rCursor->getText()->createTextCursorByRange( rCursor->getStart() );
1330
0
                                xCrsr->goLeft( 1, true );
1331
0
                                uno::Reference< beans::XPropertySet> xCrsrProperties( xCrsr, uno::UNO_QUERY_THROW );
1332
                                //the hard properties of the removed text need to be applied to the combined characters field
1333
0
                                pStyle->FillPropertySet( xCrsrProperties );
1334
0
                                xCrsr->collapseToEnd();
1335
0
                                xCrsr->gotoRange( rCursor->getEnd(), true );
1336
0
                                xCrsr->setString( OUString() );
1337
0
                            }
1338
0
                            catch(const uno::Exception&)
1339
0
                            {
1340
0
                            }
1341
0
                        }
1342
0
                    }
1343
0
                }
1344
0
            }
1345
0
        }
1346
25.2k
    }
1347
1348
    // outline level; set after list style has been set
1349
    // Complete re-worked and corrected: (#i53198#)
1350
    // - set outline level at paragraph
1351
    // - set numbering level at paragraph, if none is already set
1352
    // - assure that style is marked as an outline style for the corresponding
1353
    //   outline level.
1354
    // - DO NOT set type of numbering rule to outline.
1355
    // - DO NOT set numbering rule directly at the paragraph.
1356
1357
    // Some minor rework and adjust access to paragraph styles (#i70748#)
1358
238k
    if ( bPara )
1359
234k
    {
1360
        // Headings not numbered anymore in 3.1 (#i103817#)
1361
234k
        sal_Int16 nCurrentOutlineLevelInheritedFromParagraphStyle = 0;
1362
234k
        const bool bHasOutlineLevelProp(
1363
234k
            xPropSetInfo->hasPropertyByName(s_OutlineLevel));
1364
234k
        if ( bHasOutlineLevelProp )
1365
180k
        {
1366
180k
            xPropSet->getPropertyValue(s_OutlineLevel)
1367
180k
                >>= nCurrentOutlineLevelInheritedFromParagraphStyle;
1368
180k
        }
1369
234k
        if ( nOutlineLevel > 0 )
1370
158k
        {
1371
158k
            if ( bHasOutlineLevelProp )
1372
131k
            {
1373
                // In case that the value equals the value of its paragraph style
1374
                // attribute outline level, the paragraph attribute value is left unset
1375
131k
                if ( nCurrentOutlineLevelInheritedFromParagraphStyle != nOutlineLevel )
1376
1.00k
                {
1377
1.00k
                    xPropSet->setPropertyValue( s_OutlineLevel,
1378
1.00k
                        Any( static_cast<sal_Int16>(nOutlineLevel) ) );
1379
1.00k
                }
1380
131k
            }
1381
158k
            if (!bOutlineContentVisible)
1382
0
            {
1383
0
                uno::Sequence<beans::PropertyValue> aGrabBag;
1384
0
                xPropSet->getPropertyValue(u"ParaInteropGrabBag"_ustr) >>= aGrabBag;
1385
0
                sal_Int32 length = aGrabBag.getLength();
1386
0
                aGrabBag.realloc(length + 1);
1387
0
                auto pGrabBag = aGrabBag.getArray();
1388
0
                pGrabBag[length].Name = "OutlineContentVisibleAttr";
1389
0
                pGrabBag[length].Value <<= bool(bOutlineContentVisible);
1390
0
                xPropSet->setPropertyValue(u"ParaInteropGrabBag"_ustr, uno::Any(aGrabBag));
1391
0
            }
1392
            // RFE: inserting headings into text documents (#i70748#)
1393
158k
            if ( bApplyOutlineLevelAsListLevel )
1394
105k
            {
1395
105k
                sal_Int16 nNumLevel = -1;
1396
105k
                xPropSet->getPropertyValue( s_NumberingLevel ) >>= nNumLevel;
1397
105k
                if ( nNumLevel == -1 ||
1398
105k
                     nNumLevel != (nOutlineLevel - 1) )
1399
4
                {
1400
4
                    xPropSet->setPropertyValue( s_NumberingLevel,
1401
4
                            Any( static_cast<sal_Int8>(nOutlineLevel - 1) ) );
1402
4
                }
1403
105k
            }
1404
            /* Correction: (#i69629#)
1405
               - for text document from version OOo 2.0.4/SO 8 PU4 and earlier
1406
                 the paragraph style of a heading should be assigned to the
1407
                 corresponding list level of the outline style.
1408
               - for other text documents the paragraph style of a heading is only
1409
                 a candidate for an assignment to the list level of the outline
1410
                 style, if it has no direct list style property and (if exists) the
1411
                 automatic paragraph style has also no direct list style set.
1412
            */
1413
158k
            if (m_xImpl->m_xParaStyles.is() && m_xImpl->m_xParaStyles->hasByName(sStyleName))
1414
130k
            {
1415
130k
                bool bOutlineStyleCandidate( false );
1416
1417
130k
                sal_Int32 nUPD( 0 );
1418
130k
                sal_Int32 nBuild( 0 );
1419
130k
                const bool bBuildIdFound = rImport.getBuildIds( nUPD, nBuild );
1420
                // Lost outline numbering in master document (#i73509#)
1421
                // Check explicitly on certain versions (#i86058#)
1422
130k
                if ( rImport.IsTextDocInOOoFileFormat() ||
1423
130k
                     ( bBuildIdFound &&
1424
0
                       ( nUPD == 645 || nUPD == 641 ) ) )
1425
0
                {
1426
0
                    bOutlineStyleCandidate = true;
1427
0
                }
1428
130k
                else if ( nUPD == 680 && nBuild <= 9073 ) /* BuildId of OOo 2.0.4/SO8 PU4 */
1429
0
                {
1430
0
                    bOutlineStyleCandidate = bOutlineLevelAttrFound;
1431
0
                }
1432
130k
                if ( bOutlineStyleCandidate )
1433
0
                {
1434
0
                    AddOutlineStyleCandidate( nOutlineLevel, sStyleName );
1435
0
                }
1436
                // Assure that heading applies the outline style (#i103817#)
1437
130k
                if ( ( !pStyle || !pStyle->IsListStyleSet() ) &&
1438
130k
                     !bOutlineStyleCandidate &&
1439
130k
                     m_xImpl->m_xChapterNumbering.is())
1440
130k
                {
1441
130k
                    if ( !lcl_HasListStyle( sStyleName,
1442
130k
                                    m_xImpl->m_xParaStyles, GetXMLImport(),
1443
130k
                                    u"NumberingStyleName"_ustr,
1444
130k
                                    u"" ) )
1445
341
                    {
1446
                        // heading not in a list --> apply outline style
1447
341
                        xPropSet->setPropertyValue( s_NumberingRules,
1448
341
                            Any(m_xImpl->m_xChapterNumbering) );
1449
341
                        xPropSet->setPropertyValue( s_NumberingLevel,
1450
341
                            Any(static_cast<sal_Int8>(nOutlineLevel - 1)));
1451
341
                    }
1452
130k
                }
1453
130k
            }
1454
158k
        }
1455
        //handle for text:p,if the paragraphstyle outlinelevel is set to[1~10]
1456
75.6k
        else if( bHasOutlineLevelProp )
1457
49.2k
        {
1458
49.2k
            if ( nCurrentOutlineLevelInheritedFromParagraphStyle != 0 )
1459
6
            {
1460
6
                xPropSet->setPropertyValue(s_OutlineLevel,
1461
6
                    Any( sal_Int16(0) ));
1462
6
            }
1463
49.2k
        }
1464
234k
    }
1465
1466
238k
    return sStyleName;
1467
238k
}
1468
1469
void XMLTextImportHelper::FindOutlineStyleName( OUString& rStyleName,
1470
                                                sal_Int8 nOutlineLevel )
1471
157k
{
1472
    // style name empty?
1473
157k
    if( !rStyleName.isEmpty() )
1474
0
        return;
1475
1476
    // Empty? Then we need o do stuff. Let's do error checking first.
1477
157k
    if (m_xImpl->m_xChapterNumbering.is() &&
1478
157k
        ( nOutlineLevel > 0 ) &&
1479
157k
        (nOutlineLevel <= m_xImpl->m_xChapterNumbering->getCount()))
1480
157k
    {
1481
157k
        nOutlineLevel--;   // for the remainder, the level's are 0-based
1482
1483
        // empty style name: look-up previously used name
1484
1485
        // if we don't have a previously used name, we'll use the default
1486
157k
        m_xImpl->InitOutlineStylesCandidates();
1487
157k
        if (m_xImpl->m_xOutlineStylesCandidates[nOutlineLevel].empty())
1488
2.00k
        {
1489
            // no other name used previously? Then use default
1490
1491
            // iterate over property value sequence to find the style name
1492
2.00k
            Sequence<PropertyValue> aProperties;
1493
2.00k
            m_xImpl->m_xChapterNumbering->getByIndex( nOutlineLevel )
1494
2.00k
                >>= aProperties;
1495
2.00k
            auto pProp = std::find_if(std::cbegin(aProperties), std::cend(aProperties),
1496
26.1k
                [](const PropertyValue& rProp) { return rProp.Name == "HeadingStyleName"; });
1497
2.00k
            if (pProp != std::cend(aProperties))
1498
2.00k
            {
1499
2.00k
                OUString aOutlineStyle;
1500
2.00k
                pProp->Value >>= aOutlineStyle;
1501
2.00k
                m_xImpl->m_xOutlineStylesCandidates[nOutlineLevel]
1502
2.00k
                    .push_back( aOutlineStyle );
1503
2.00k
            }
1504
2.00k
        }
1505
1506
        // finally, we'll use the previously used style name for this
1507
        // format (or the default we've just put into that style)
1508
        // take last added one (#i71249#)
1509
157k
        rStyleName =
1510
157k
            m_xImpl->m_xOutlineStylesCandidates[nOutlineLevel].back();
1511
157k
    }
1512
    // else: nothing we can do, so we'll leave it empty
1513
    // else: we already had a style name, so we let it pass.
1514
157k
}
1515
1516
void XMLTextImportHelper::AddOutlineStyleCandidate( const sal_Int8 nOutlineLevel,
1517
                                                    const OUString& rStyleName )
1518
2.26k
{
1519
2.26k
    if (!rStyleName.isEmpty()
1520
2.26k
        && m_xImpl->m_xChapterNumbering.is()
1521
2.26k
        && (nOutlineLevel > 0)
1522
2.26k
        && (nOutlineLevel <= m_xImpl->m_xChapterNumbering->getCount()))
1523
2.26k
    {
1524
2.26k
        m_xImpl->InitOutlineStylesCandidates();
1525
2.26k
        m_xImpl->m_xOutlineStylesCandidates[nOutlineLevel-1].push_back(
1526
2.26k
            rStyleName);
1527
2.26k
    }
1528
2.26k
}
1529
1530
void XMLTextImportHelper::SetOutlineStyles( bool bSetEmptyLevels )
1531
24.5k
{
1532
24.5k
    if (!(m_xImpl->m_xOutlineStylesCandidates != nullptr || bSetEmptyLevels) ||
1533
14.4k
        !m_xImpl->m_xChapterNumbering.is() ||
1534
14.4k
        IsInsertMode())
1535
10.1k
        return;
1536
1537
14.4k
    bool bChooseLastOne( false );
1538
1539
14.4k
    if ( GetXMLImport().IsTextDocInOOoFileFormat() )
1540
0
    {
1541
0
        bChooseLastOne = true;
1542
0
    }
1543
14.4k
    else
1544
14.4k
    {
1545
14.4k
        sal_Int32 nUPD( 0 );
1546
14.4k
        sal_Int32 nBuild( 0 );
1547
14.4k
        if ( GetXMLImport().getBuildIds( nUPD, nBuild ) )
1548
138
        {
1549
            // check explicitly on certain versions
1550
138
            bChooseLastOne = ( nUPD == 641 ) || ( nUPD == 645 ) ||  // prior OOo 2.0
1551
138
                             ( nUPD == 680 && nBuild <= 9073 ); // OOo 2.0 - OOo 2.0.4
1552
138
        }
1553
14.4k
    }
1554
1555
14.4k
    OUString sOutlineStyleName;
1556
14.4k
    {
1557
14.4k
        Reference<XPropertySet> xChapterNumRule(
1558
14.4k
            m_xImpl->m_xChapterNumbering, UNO_QUERY);
1559
14.4k
        xChapterNumRule->getPropertyValue(u"Name"_ustr) >>= sOutlineStyleName;
1560
14.4k
    }
1561
1562
14.4k
    const sal_Int32 nCount = m_xImpl->m_xChapterNumbering->getCount();
1563
    /* First collect all paragraph styles chosen for assignment to each
1564
       list level of the outline style, then perform the intrinsic assignment.
1565
       Reason: The assignment of a certain paragraph style to a list level
1566
               of the outline style causes side effects on the children
1567
               paragraph styles in Writer. (#i106218#)
1568
    */
1569
14.4k
    ::std::vector<OUString> sChosenStyles(nCount);
1570
159k
    for( sal_Int32 i=0; i < nCount; ++i )
1571
144k
    {
1572
144k
        if ( bSetEmptyLevels ||
1573
67.1k
             (m_xImpl->m_xOutlineStylesCandidates &&
1574
67.1k
              !m_xImpl->m_xOutlineStylesCandidates[i].empty()))
1575
85.3k
        {
1576
            // determine, which candidate is one to be assigned to the list
1577
            // level of the outline style
1578
85.3k
            if (m_xImpl->m_xOutlineStylesCandidates &&
1579
11.0k
                !m_xImpl->m_xOutlineStylesCandidates[i].empty())
1580
9.03k
            {
1581
9.03k
                if ( bChooseLastOne )
1582
0
                {
1583
0
                    sChosenStyles[i] =
1584
0
                    m_xImpl->m_xOutlineStylesCandidates[i].back();
1585
0
                }
1586
9.03k
                else
1587
9.03k
                {
1588
9.03k
                    for (size_t j = 0;
1589
10.4k
                        j < m_xImpl->m_xOutlineStylesCandidates[i].size();
1590
9.03k
                        ++j)
1591
9.22k
                    {
1592
9.22k
                        if (!lcl_HasListStyle(
1593
9.22k
                                m_xImpl->m_xOutlineStylesCandidates[i][j],
1594
9.22k
                                m_xImpl->m_xParaStyles,
1595
9.22k
                                GetXMLImport(),
1596
9.22k
                                u"NumberingStyleName"_ustr,
1597
9.22k
                                sOutlineStyleName))
1598
7.79k
                        {
1599
7.79k
                            sChosenStyles[i] =
1600
7.79k
                                m_xImpl->m_xOutlineStylesCandidates[i][j];
1601
7.79k
                            break;
1602
7.79k
                        }
1603
9.22k
                    }
1604
9.03k
                }
1605
9.03k
            }
1606
85.3k
        }
1607
144k
    }
1608
    // Trashed outline numbering in ODF 1.1 text document created by OOo 3.x (#i106218#)
1609
14.4k
    Sequence < PropertyValue > aProps( 1 );
1610
14.4k
    PropertyValue *pProps = aProps.getArray();
1611
14.4k
    pProps->Name = "HeadingStyleName";
1612
159k
    for ( sal_Int32 i = 0; i < nCount; ++i )
1613
144k
    {
1614
        // Paragraph style assignments in Outline of template lost from second level on (#i107610#)
1615
144k
        if ( bSetEmptyLevels || !sChosenStyles[i].isEmpty() )
1616
84.7k
        {
1617
84.7k
            pProps->Value <<= sChosenStyles[i];
1618
84.7k
            m_xImpl->m_xChapterNumbering->replaceByIndex(i,
1619
84.7k
                    Any( aProps ));
1620
84.7k
        }
1621
144k
    }
1622
1623
14.4k
}
1624
1625
void XMLTextImportHelper::SetHyperlink(
1626
    SvXMLImport const & rImport,
1627
    const Reference < XTextCursor >& rCursor,
1628
    const OUString& rHRef,
1629
    const OUString& rName,
1630
    const OUString& rTargetFrameName,
1631
    const OUString& rStyleName,
1632
    const OUString& rVisitedStyleName,
1633
    XMLEventsImportContext* pEvents)
1634
0
{
1635
0
    static constexpr OUString s_HyperLinkURL = u"HyperLinkURL"_ustr;
1636
0
    static constexpr OUString s_HyperLinkName = u"HyperLinkName"_ustr;
1637
0
    static constexpr OUString s_HyperLinkTarget = u"HyperLinkTarget"_ustr;
1638
0
    static constexpr OUString s_UnvisitedCharStyleName = u"UnvisitedCharStyleName"_ustr;
1639
0
    static constexpr OUString s_VisitedCharStyleName = u"VisitedCharStyleName"_ustr;
1640
0
    static constexpr OUString s_HyperLinkEvents = u"HyperLinkEvents"_ustr;
1641
1642
0
    Reference < XPropertySet > xPropSet( rCursor, UNO_QUERY );
1643
0
    Reference < XPropertySetInfo > xPropSetInfo(
1644
0
        xPropSet->getPropertySetInfo());
1645
0
    if (!xPropSetInfo.is() || !xPropSetInfo->hasPropertyByName(s_HyperLinkURL))
1646
0
        return;
1647
1648
0
    xPropSet->setPropertyValue(s_HyperLinkURL, Any(rHRef));
1649
1650
0
    if (xPropSetInfo->hasPropertyByName(s_HyperLinkName))
1651
0
    {
1652
0
        xPropSet->setPropertyValue(s_HyperLinkName, Any(rName));
1653
0
    }
1654
1655
0
    if (xPropSetInfo->hasPropertyByName(s_HyperLinkTarget))
1656
0
    {
1657
0
        xPropSet->setPropertyValue(s_HyperLinkTarget,
1658
0
            Any(rTargetFrameName));
1659
0
    }
1660
1661
0
    if ( (pEvents != nullptr) &&
1662
0
        xPropSetInfo->hasPropertyByName(s_HyperLinkEvents))
1663
0
    {
1664
        // The API treats events at hyperlinks differently from most
1665
        // other properties: You have to set a name replace with the
1666
        // events in it. The easiest way to do this is to 1) get
1667
        // events, 2) set new ones, and 3) then put events back.
1668
0
        uno::Reference<XNameReplace> const xReplace(
1669
0
            xPropSet->getPropertyValue(s_HyperLinkEvents), UNO_QUERY);
1670
0
        if (xReplace.is())
1671
0
        {
1672
            // set events
1673
0
            pEvents->SetEvents(xReplace);
1674
1675
            // put events
1676
0
            xPropSet->setPropertyValue(s_HyperLinkEvents, Any(xReplace));
1677
0
        }
1678
0
    }
1679
1680
0
    if (!m_xImpl->m_xTextStyles.is())
1681
0
        return;
1682
1683
0
    OUString sDisplayName(
1684
0
        rImport.GetStyleDisplayName(
1685
0
                        XmlStyleFamily::TEXT_TEXT, rStyleName ) );
1686
0
    if( !sDisplayName.isEmpty() &&
1687
0
        xPropSetInfo->hasPropertyByName(s_UnvisitedCharStyleName) &&
1688
0
        m_xImpl->m_xTextStyles->hasByName(sDisplayName))
1689
0
    {
1690
0
        xPropSet->setPropertyValue(s_UnvisitedCharStyleName,
1691
0
            Any(sDisplayName));
1692
0
    }
1693
1694
0
    sDisplayName =
1695
0
        rImport.GetStyleDisplayName(
1696
0
                        XmlStyleFamily::TEXT_TEXT, rVisitedStyleName );
1697
0
    if( !sDisplayName.isEmpty() &&
1698
0
        xPropSetInfo->hasPropertyByName(s_VisitedCharStyleName) &&
1699
0
        m_xImpl->m_xTextStyles->hasByName(sDisplayName))
1700
0
    {
1701
0
        xPropSet->setPropertyValue(s_VisitedCharStyleName,
1702
0
            Any(sDisplayName));
1703
0
    }
1704
0
}
1705
1706
void XMLTextImportHelper::SetRuby(
1707
    SvXMLImport const & rImport,
1708
    const Reference < XTextCursor >& rCursor,
1709
    const OUString& rStyleName,
1710
    const OUString& rTextStyleName,
1711
    const OUString& rText )
1712
2.60k
{
1713
2.60k
    Reference<XPropertySet> xPropSet(rCursor, UNO_QUERY);
1714
1715
2.60k
    OUString sRubyText(u"RubyText"_ustr);
1716
1717
    // if we have one Ruby property, we assume all of them are present
1718
2.60k
    if (!xPropSet.is() ||
1719
2.60k
        !xPropSet->getPropertySetInfo()->hasPropertyByName( sRubyText ))
1720
0
        return;
1721
1722
    // the ruby text
1723
2.60k
    xPropSet->setPropertyValue(sRubyText, Any(rText));
1724
1725
    // the ruby style (ruby-adjust)
1726
2.60k
    if (!rStyleName.isEmpty() && m_xImpl->m_xAutoStyles.is())
1727
704
    {
1728
704
        const SvXMLStyleContext* pTempStyle =
1729
704
            m_xImpl->m_xAutoStyles->FindStyleChildContext( XmlStyleFamily::TEXT_RUBY,
1730
704
                                   rStyleName, true );
1731
704
        XMLPropStyleContext *pStyle = const_cast<XMLPropStyleContext*>(dynamic_cast< const XMLPropStyleContext* >(pTempStyle));
1732
1733
704
        if (nullptr != pStyle)
1734
139
            pStyle->FillPropertySet( xPropSet );
1735
704
    }
1736
1737
    // the ruby text character style
1738
2.60k
    if (m_xImpl->m_xTextStyles.is())
1739
2.60k
    {
1740
2.60k
        OUString sDisplayName(
1741
2.60k
            rImport.GetStyleDisplayName(
1742
2.60k
                        XmlStyleFamily::TEXT_TEXT, rTextStyleName ) );
1743
2.60k
        if( (!sDisplayName.isEmpty()) &&
1744
0
            m_xImpl->m_xTextStyles->hasByName( sDisplayName ))
1745
0
        {
1746
0
            xPropSet->setPropertyValue(u"RubyCharStyleName"_ustr, Any(sDisplayName));
1747
0
        }
1748
2.60k
    }
1749
2.60k
}
1750
1751
void XMLTextImportHelper::SetAutoStyles( SvXMLStylesContext *pStyles )
1752
9.49k
{
1753
9.49k
    m_xImpl->m_xAutoStyles = pStyles;
1754
9.49k
}
1755
1756
SvXMLImportContext *XMLTextImportHelper::CreateTextChildContext(
1757
        SvXMLImport& rImport,
1758
        sal_Int32 nElement,
1759
        const Reference< XFastAttributeList > & xAttrList,
1760
        XMLTextType eType )
1761
353k
{
1762
353k
    SvXMLImportContext *pContext = nullptr;
1763
1764
353k
    bool bContent = true;
1765
353k
    switch( nElement )
1766
353k
    {
1767
117k
    case XML_ELEMENT(TEXT, XML_H):
1768
190k
    case XML_ELEMENT(TEXT, XML_P):
1769
190k
    case XML_ELEMENT(LO_EXT, XML_P):
1770
190k
        pContext = new XMLParaContext( rImport,
1771
190k
                                       nElement,
1772
190k
                                       xAttrList );
1773
190k
        if (m_xImpl->m_bProgress && XMLTextType::Shape != eType)
1774
151k
        {
1775
151k
            rImport.GetProgressBarHelper()->Increment();
1776
151k
        }
1777
190k
        break;
1778
    // #i52127#
1779
14.3k
    case XML_ELEMENT(TEXT, XML_NUMBERED_PARAGRAPH):
1780
14.3k
        pContext = new XMLNumberedParaContext(
1781
14.3k
                        rImport, nElement, xAttrList );
1782
14.3k
        break;
1783
80.4k
    case XML_ELEMENT(TEXT, XML_LIST):
1784
80.4k
        pContext = new XMLTextListBlockContext( rImport, *this,
1785
80.4k
                                                xAttrList );
1786
80.4k
        break;
1787
3.86k
    case XML_ELEMENT(TABLE,XML_TABLE):
1788
3.86k
    case XML_ELEMENT(LO_EXT, XML_TABLE):
1789
3.86k
        if( XMLTextType::Body == eType ||
1790
311
            XMLTextType::TextBox == eType ||
1791
311
             XMLTextType::Section == eType ||
1792
311
            XMLTextType::HeaderFooter == eType ||
1793
8
            XMLTextType::ChangedRegion == eType ||
1794
8
            XMLTextType::Cell == eType )
1795
3.86k
            pContext = CreateTableChildContext( rImport, nElement, xAttrList );
1796
3.86k
        break;
1797
1.64k
    case XML_ELEMENT(TEXT, XML_SEQUENCE_DECLS):
1798
1.64k
        if ((XMLTextType::Body == eType && m_xImpl->m_bBodyContentStarted) ||
1799
8
            XMLTextType::HeaderFooter == eType )
1800
1.63k
        {
1801
1.63k
            pContext = new XMLVariableDeclsImportContext(
1802
1.63k
                rImport, *this, VarTypeSequence);
1803
1.63k
            bContent = false;
1804
1.63k
        }
1805
1.64k
        break;
1806
1
    case XML_ELEMENT(TEXT, XML_VARIABLE_DECLS):
1807
1
        if ((XMLTextType::Body == eType && m_xImpl->m_bBodyContentStarted) ||
1808
1
            XMLTextType::HeaderFooter == eType )
1809
0
        {
1810
0
            pContext = new XMLVariableDeclsImportContext(
1811
0
                rImport, *this, VarTypeSimple);
1812
0
            bContent = false;
1813
0
        }
1814
1
        break;
1815
0
    case XML_ELEMENT(TEXT, XML_USER_FIELD_DECLS):
1816
0
        if ((XMLTextType::Body == eType && m_xImpl->m_bBodyContentStarted)||
1817
0
            XMLTextType::HeaderFooter == eType )
1818
0
        {
1819
0
            pContext = new XMLVariableDeclsImportContext(
1820
0
                rImport, *this, VarTypeUserField);
1821
0
            bContent = false;
1822
0
        }
1823
0
        break;
1824
0
    case XML_ELEMENT(TEXT, XML_DDE_CONNECTION_DECLS):
1825
0
        if ((XMLTextType::Body == eType && m_xImpl->m_bBodyContentStarted) ||
1826
0
            XMLTextType::HeaderFooter == eType )
1827
0
        {
1828
0
            pContext = new XMLDdeFieldDeclsImportContext(rImport);
1829
0
            bContent = false;
1830
0
        }
1831
0
        break;
1832
8.64k
    case XML_ELEMENT(DRAW, XML_FRAME):
1833
8.64k
        if ((XMLTextType::Body == eType && m_xImpl->m_bBodyContentStarted) ||
1834
394
            XMLTextType::TextBox == eType ||
1835
75
            XMLTextType::ChangedRegion == eType )
1836
8.56k
        {
1837
8.56k
            TextContentAnchorType eAnchorType =
1838
8.56k
                XMLTextType::TextBox == eType ? TextContentAnchorType_AT_FRAME
1839
8.56k
                                               : TextContentAnchorType_AT_PAGE;
1840
8.56k
            pContext = new XMLTextFrameContext( rImport, xAttrList,
1841
8.56k
                                                eAnchorType );
1842
8.56k
            bContent = false;
1843
8.56k
        }
1844
8.64k
        break;
1845
22
    case XML_ELEMENT(DRAW, XML_A):
1846
22
        if ((XMLTextType::Body == eType && m_xImpl->m_bBodyContentStarted) ||
1847
16
            XMLTextType::TextBox == eType ||
1848
16
             XMLTextType::ChangedRegion == eType)
1849
6
        {
1850
6
            TextContentAnchorType eAnchorType =
1851
6
                XMLTextType::TextBox == eType ? TextContentAnchorType_AT_FRAME
1852
6
                                               : TextContentAnchorType_AT_PAGE;
1853
6
            pContext = new XMLTextFrameHyperlinkContext( rImport, nElement,
1854
6
                                                xAttrList,
1855
6
                                                eAnchorType );
1856
6
            bContent = false;
1857
6
        }
1858
22
        break;
1859
2.66k
    case XML_ELEMENT(TEXT, XML_INDEX_TITLE):
1860
2.72k
    case XML_ELEMENT(TEXT, XML_SECTION):
1861
2.72k
        pContext = new XMLSectionImportContext( rImport );
1862
2.72k
        break;
1863
2.29k
    case XML_ELEMENT(TEXT, XML_TABLE_OF_CONTENT):
1864
2.29k
    case XML_ELEMENT(TEXT, XML_OBJECT_INDEX):
1865
2.29k
    case XML_ELEMENT(TEXT, XML_TABLE_INDEX):
1866
2.29k
    case XML_ELEMENT(TEXT, XML_ILLUSTRATION_INDEX):
1867
3.50k
    case XML_ELEMENT(TEXT, XML_USER_INDEX):
1868
3.51k
    case XML_ELEMENT(TEXT, XML_ALPHABETICAL_INDEX):
1869
3.63k
    case XML_ELEMENT(TEXT, XML_BIBLIOGRAPHY):
1870
3.63k
        if( XMLTextType::Shape != eType )
1871
3.54k
            pContext = new XMLIndexTOCContext( rImport, nElement );
1872
3.63k
        break;
1873
225
    case XML_ELEMENT(TEXT, XML_TRACKED_CHANGES):
1874
225
        pContext = new XMLTrackedChangesImportContext( rImport );
1875
225
        bContent = false;
1876
225
        break;
1877
2
    case XML_ELEMENT(TEXT, XML_CHANGE):
1878
2
    case XML_ELEMENT(TEXT, XML_CHANGE_START):
1879
14
    case XML_ELEMENT(TEXT, XML_CHANGE_END):
1880
14
        pContext = new XMLChangeImportContext(
1881
14
            rImport,
1882
14
            ((nElement == XML_ELEMENT(TEXT, XML_CHANGE_END))
1883
14
                ? XMLChangeImportContext::Element::END
1884
14
                : (nElement == XML_ELEMENT(TEXT, XML_CHANGE_START))
1885
2
                    ? XMLChangeImportContext::Element::START
1886
2
                    : XMLChangeImportContext::Element::POINT),
1887
14
            true);
1888
14
        break;
1889
106
    case XML_ELEMENT(OFFICE, XML_FORMS):
1890
106
        pContext = xmloff::OFormLayerXMLImport::createOfficeFormsContext(rImport);
1891
106
        bContent = false;
1892
106
        break;
1893
2
    case XML_ELEMENT(TEXT, XML_ALPHABETICAL_INDEX_AUTO_MARK_FILE):
1894
2
        if( XMLTextType::Body == eType )
1895
2
        {
1896
2
            pContext = new XMLAutoMarkFileContext(rImport);
1897
2
        }
1898
2
        bContent = false;
1899
2
        break;
1900
4
    case XML_ELEMENT(TABLE, XML_CALCULATION_SETTINGS):
1901
4
        pContext = new XMLCalculationSettingsContext ( rImport, nElement, xAttrList);
1902
4
        bContent = false;
1903
4
        break;
1904
1905
47.6k
    default:
1906
47.6k
        if ((XMLTextType::Body == eType && m_xImpl->m_bBodyContentStarted) ||
1907
43.5k
            XMLTextType::TextBox == eType ||
1908
43.3k
             XMLTextType::ChangedRegion == eType )
1909
4.26k
        {
1910
4.26k
            Reference < XShapes > xShapes;
1911
4.26k
            pContext = XMLShapeImportHelper::CreateGroupChildContext(
1912
4.26k
                    rImport, nElement, xAttrList, xShapes );
1913
4.26k
            bContent = false;
1914
4.26k
        }
1915
353k
    }
1916
1917
    // handle open redlines
1918
353k
    if ( (XML_ELEMENT(TEXT, XML_CHANGE) != nElement) &&
1919
353k
         (XML_ELEMENT(TEXT, XML_CHANGE_END) != nElement) &&
1920
353k
         (XML_ELEMENT(TEXT, XML_CHANGE_START) != nElement) )
1921
353k
    {
1922
//      ResetOpenRedlineId();
1923
353k
    }
1924
1925
353k
    if( XMLTextType::Body == eType && bContent )
1926
197k
    {
1927
197k
        m_xImpl->m_bBodyContentStarted = false;
1928
197k
    }
1929
1930
353k
    if( nElement != XML_ELEMENT(DRAW, XML_FRAME) )
1931
345k
        ClearLastImportedTextFrameName();
1932
1933
353k
    if (!pContext)
1934
353k
        XMLOFF_WARN_UNKNOWN_ELEMENT("xmloff", nElement);
1935
1936
353k
    return pContext;
1937
353k
}
1938
1939
SvXMLImportContext *XMLTextImportHelper::CreateTableChildContext(
1940
        SvXMLImport&,
1941
        sal_Int32 /*nElement*/,
1942
        const Reference< XFastAttributeList > & )
1943
0
{
1944
0
    return nullptr;
1945
0
}
1946
1947
/// get data style key for use with NumberFormat property
1948
sal_Int32 XMLTextImportHelper::GetDataStyleKey(const OUString& sStyleName,
1949
                                               bool* pIsSystemLanguage )
1950
2.34k
{
1951
2.34k
    if (!m_xImpl->m_xAutoStyles.is())
1952
1.99k
        return -1;
1953
1954
348
    const SvXMLStyleContext* pStyle =
1955
348
        m_xImpl->m_xAutoStyles->FindStyleChildContext( XmlStyleFamily::DATA_STYLE,
1956
348
                                              sStyleName, true );
1957
1958
    // get appropriate context
1959
1960
1961
    // first check if it's an Impress and draw only number format
1962
    // this is needed since it's also a SvXMLNumFormatContext,
1963
    // that was needed to support them for controls in impress/draw also
1964
348
    const SdXMLNumberFormatImportContext* pSdNumStyle = dynamic_cast<const SdXMLNumberFormatImportContext*>( pStyle  );
1965
348
    if( pSdNumStyle )
1966
0
    {
1967
0
        return pSdNumStyle->GetDrawKey();
1968
0
    }
1969
348
    else
1970
348
    {
1971
348
        SvXMLNumFormatContext* pNumStyle = const_cast<SvXMLNumFormatContext*>(dynamic_cast<const SvXMLNumFormatContext*>( pStyle ) );
1972
348
        if( pNumStyle )
1973
310
        {
1974
310
            if( pIsSystemLanguage != nullptr )
1975
291
                *pIsSystemLanguage = pNumStyle->IsSystemLanguage();
1976
1977
            // return key
1978
310
            return pNumStyle->GetKey();
1979
310
        }
1980
348
    }
1981
38
    return -1;
1982
348
}
1983
1984
const SvxXMLListStyleContext *XMLTextImportHelper::FindAutoListStyle( const OUString& rName ) const
1985
0
{
1986
0
    const SvxXMLListStyleContext *pStyle = nullptr;
1987
0
    if (m_xImpl->m_xAutoStyles.is())
1988
0
    {
1989
0
        const SvXMLStyleContext* pTempStyle =
1990
0
            m_xImpl->m_xAutoStyles->FindStyleChildContext( XmlStyleFamily::TEXT_LIST, rName,
1991
0
                                           true );
1992
0
        pStyle = dynamic_cast< const SvxXMLListStyleContext* >(pTempStyle);
1993
0
    }
1994
1995
0
    return pStyle;
1996
0
}
1997
1998
XMLPropStyleContext *XMLTextImportHelper::FindAutoFrameStyle( const OUString& rName ) const
1999
52.3k
{
2000
52.3k
    XMLPropStyleContext *pStyle = nullptr;
2001
52.3k
    if (m_xImpl->m_xAutoStyles.is())
2002
5.27k
    {
2003
5.27k
        const SvXMLStyleContext* pTempStyle =
2004
5.27k
            m_xImpl->m_xAutoStyles->FindStyleChildContext( XmlStyleFamily::SD_GRAPHICS_ID, rName,
2005
5.27k
                                           true );
2006
5.27k
        pStyle = const_cast<XMLPropStyleContext*>(dynamic_cast< const XMLPropStyleContext* >(pTempStyle));
2007
5.27k
    }
2008
2009
52.3k
    return pStyle;
2010
52.3k
}
2011
2012
XMLPropStyleContext* XMLTextImportHelper::FindSectionStyle(
2013
    const OUString& rName ) const
2014
196
{
2015
196
    XMLPropStyleContext* pStyle = nullptr;
2016
196
    if (m_xImpl->m_xAutoStyles.is())
2017
181
    {
2018
181
        const SvXMLStyleContext* pTempStyle =
2019
181
            m_xImpl->m_xAutoStyles->FindStyleChildContext(
2020
181
                               XmlStyleFamily::TEXT_SECTION,
2021
181
                               rName, true );
2022
181
        pStyle = const_cast<XMLPropStyleContext*>(dynamic_cast< const XMLPropStyleContext* >(pTempStyle));
2023
181
    }
2024
2025
196
    return pStyle;
2026
196
}
2027
2028
XMLPropStyleContext* XMLTextImportHelper::FindPageMaster(
2029
    const OUString& rName ) const
2030
10.9k
{
2031
10.9k
    XMLPropStyleContext* pStyle = nullptr;
2032
10.9k
    if (m_xImpl->m_xAutoStyles.is())
2033
10.7k
    {
2034
10.7k
        const SvXMLStyleContext* pTempStyle =
2035
10.7k
            m_xImpl->m_xAutoStyles->FindStyleChildContext(
2036
10.7k
                               XmlStyleFamily::PAGE_MASTER,
2037
10.7k
                               rName, true );
2038
10.7k
        pStyle = const_cast<XMLPropStyleContext*>(dynamic_cast< const XMLPropStyleContext* >(pTempStyle));
2039
10.7k
    }
2040
2041
10.9k
    return pStyle;
2042
10.9k
}
2043
2044
XMLPropStyleContext* XMLTextImportHelper::FindAutoCharStyle(const OUString& rName) const
2045
0
{
2046
0
    if (!m_xImpl->m_xAutoStyles)
2047
0
        return nullptr;
2048
0
    auto pStyle
2049
0
        = m_xImpl->m_xAutoStyles->FindStyleChildContext(XmlStyleFamily::TEXT_TEXT, rName, true);
2050
0
    return dynamic_cast<XMLPropStyleContext*>(const_cast<SvXMLStyleContext*>(pStyle));
2051
0
}
2052
2053
XMLPropStyleContext * XMLTextImportHelper::FindDrawingPage(OUString const& rName) const
2054
4.81k
{
2055
4.81k
    if (!m_xImpl->m_xAutoStyles.is())
2056
119
    {
2057
119
        return nullptr;
2058
119
    }
2059
4.69k
    SvXMLStyleContext const* pStyle(
2060
4.69k
        m_xImpl->m_xAutoStyles->FindStyleChildContext(
2061
4.69k
               XmlStyleFamily::SD_DRAWINGPAGE_ID, rName, true));
2062
4.69k
    assert(pStyle == nullptr || dynamic_cast<XMLPropStyleContext const*>(pStyle) != nullptr);
2063
4.69k
    return const_cast<XMLPropStyleContext*>(static_cast<XMLPropStyleContext const*>(pStyle));
2064
4.81k
}
2065
2066
void XMLTextImportHelper::PushListContext()
2067
30.1k
{
2068
30.1k
    GetTextListHelper().PushListContext(static_cast<XMLTextListBlockContext*>(nullptr));
2069
30.1k
}
2070
2071
void XMLTextImportHelper::PopListContext()
2072
40.3k
{
2073
40.3k
    GetTextListHelper().PopListContext();
2074
40.3k
}
2075
2076
2077
SvI18NMap& XMLTextImportHelper::GetRenameMap()
2078
53.8k
{
2079
53.8k
    if (!m_xImpl->m_xRenameMap)
2080
2.77k
    {
2081
2.77k
        m_xImpl->m_xRenameMap.reset( new SvI18NMap );
2082
2.77k
    }
2083
53.8k
    return *m_xImpl->m_xRenameMap;
2084
53.8k
}
2085
2086
void XMLTextImportHelper::InsertBookmarkStartRange(
2087
    const OUString & sName,
2088
    const Reference<XTextRange> & rRange,
2089
    OUString const& i_rXmlId,
2090
    std::shared_ptr< ::xmloff::ParsedRDFaAttributes > & i_rpRDFaAttributes)
2091
35
{
2092
35
    m_xImpl->m_BookmarkStartRanges[sName] =
2093
35
        std::make_tuple(rRange, i_rXmlId, i_rpRDFaAttributes);
2094
35
    m_xImpl->m_BookmarkVector.push_back(sName);
2095
35
}
2096
2097
bool XMLTextImportHelper::FindAndRemoveBookmarkStartRange(
2098
    const OUString & sName,
2099
    Reference<XTextRange> & o_rRange,
2100
    OUString & o_rXmlId,
2101
    std::shared_ptr< ::xmloff::ParsedRDFaAttributes > & o_rpRDFaAttributes)
2102
253
{
2103
253
    if (m_xImpl->m_BookmarkStartRanges.count(sName))
2104
31
    {
2105
31
        Impl::BookmarkMapEntry_t & rEntry =
2106
31
            (*m_xImpl->m_BookmarkStartRanges.find(sName)).second;
2107
31
        o_rRange.set(std::get<0>(rEntry));
2108
31
        o_rXmlId = std::get<1>(rEntry);
2109
31
        o_rpRDFaAttributes = std::get<2>(rEntry);
2110
31
        m_xImpl->m_BookmarkStartRanges.erase(sName);
2111
31
        auto it = std::find(m_xImpl->m_BookmarkVector.begin(), m_xImpl->m_BookmarkVector.end(), sName);
2112
31
        if (it!=m_xImpl->m_BookmarkVector.end())
2113
31
        {
2114
31
            m_xImpl->m_BookmarkVector.erase(it);
2115
31
        }
2116
31
        return true;
2117
31
    }
2118
222
    else
2119
222
    {
2120
222
        return false;
2121
222
    }
2122
253
}
2123
2124
void XMLTextImportHelper::pushFieldCtx( const OUString& name, const OUString& type )
2125
14
{
2126
14
    m_xImpl->m_FieldStack.push(Impl::field_stack_item_t(
2127
14
        Impl::field_name_type_t(name, type), Impl::field_params_t(), uno::Reference<text::XFormField>{}, GetCursor()->getStart()));
2128
14
}
2129
2130
uno::Reference<text::XFormField>
2131
XMLTextImportHelper::popFieldCtx()
2132
12
{
2133
12
    uno::Reference<text::XFormField> xRet;
2134
12
    if ( !m_xImpl->m_FieldStack.empty() )
2135
12
    {
2136
12
        xRet = std::get<2>(m_xImpl->m_FieldStack.top());
2137
12
        m_xImpl->m_FieldStack.pop();
2138
12
    }
2139
0
    else
2140
0
    {
2141
0
        SAL_INFO("xmloff.text", "unexpected fieldmark end");
2142
0
    }
2143
12
    return xRet;
2144
12
}
2145
2146
void XMLTextImportHelper::addFieldParam( const OUString& name, const OUString& value )
2147
28
{
2148
28
    assert(!m_xImpl->m_FieldStack.empty());
2149
28
    Impl::field_stack_item_t & FieldStackItem(m_xImpl->m_FieldStack.top());
2150
28
    std::get<1>(FieldStackItem).emplace_back( name, value );
2151
28
}
2152
2153
::std::pair<OUString, OUString> XMLTextImportHelper::getCurrentFieldType() const
2154
12
{
2155
12
    assert(!m_xImpl->m_FieldStack.empty());
2156
12
    return std::get<0>(m_xImpl->m_FieldStack.top());
2157
12
}
2158
2159
uno::Reference<text::XTextRange> XMLTextImportHelper::getCurrentFieldStart() const
2160
12
{
2161
12
    assert(!m_xImpl->m_FieldStack.empty());
2162
12
    return std::get<3>(m_xImpl->m_FieldStack.top());
2163
12
}
2164
2165
bool XMLTextImportHelper::hasCurrentFieldSeparator() const
2166
12
{
2167
12
    assert(!m_xImpl->m_FieldStack.empty());
2168
12
    return std::get<2>(m_xImpl->m_FieldStack.top()).is();
2169
12
}
2170
2171
bool XMLTextImportHelper::hasCurrentFieldCtx() const
2172
41
{
2173
41
    return !m_xImpl->m_FieldStack.empty();
2174
41
}
2175
2176
void XMLTextImportHelper::setCurrentFieldParamsTo(css::uno::Reference< css::text::XFormField> const &xFormField)
2177
12
{
2178
12
    assert(!m_xImpl->m_FieldStack.empty());
2179
12
    if (xFormField.is())
2180
12
    {
2181
12
        FieldParamImporter(&std::get<1>(m_xImpl->m_FieldStack.top()),
2182
12
            xFormField->getParameters()).Import();
2183
12
        std::get<2>(m_xImpl->m_FieldStack.top()) = xFormField;
2184
12
    }
2185
12
}
2186
2187
2188
void XMLTextImportHelper::ConnectFrameChains(
2189
        const OUString& rFrmName,
2190
        const OUString& rNextFrmName,
2191
        const Reference < XPropertySet >& rFrmPropSet )
2192
23.3k
{
2193
23.3k
    if( rFrmName.isEmpty() )
2194
13.9k
        return;
2195
2196
9.39k
    if( !rNextFrmName.isEmpty() )
2197
0
    {
2198
0
        OUString sNextFrmName(GetRenameMap().Get( XML_TEXT_RENAME_TYPE_FRAME,
2199
0
                                                    rNextFrmName ));
2200
0
        if (m_xImpl->m_xTextFrames.is()
2201
0
            && m_xImpl->m_xTextFrames->hasByName(sNextFrmName))
2202
0
        {
2203
0
            rFrmPropSet->setPropertyValue(u"ChainNextName"_ustr,
2204
0
                Any(sNextFrmName));
2205
0
        }
2206
0
        else
2207
0
        {
2208
0
            if (!m_xImpl->m_xPrevFrmNames)
2209
0
            {
2210
0
                m_xImpl->m_xPrevFrmNames.emplace();
2211
0
                m_xImpl->m_xNextFrmNames.emplace();
2212
0
            }
2213
0
            m_xImpl->m_xPrevFrmNames->push_back(rFrmName);
2214
0
            m_xImpl->m_xNextFrmNames->push_back(sNextFrmName);
2215
0
        }
2216
0
    }
2217
9.39k
    if (!m_xImpl->m_xPrevFrmNames || m_xImpl->m_xPrevFrmNames->empty())
2218
9.39k
        return;
2219
2220
0
    for(std::vector<OUString>::iterator i = m_xImpl->m_xPrevFrmNames->begin(), j = m_xImpl->m_xNextFrmNames->begin(); i != m_xImpl->m_xPrevFrmNames->end() && j != m_xImpl->m_xNextFrmNames->end(); ++i, ++j)
2221
0
    {
2222
0
        if((*j) == rFrmName)
2223
0
        {
2224
            // The previous frame must exist, because it existed when
2225
            // inserting the entry
2226
0
            rFrmPropSet->setPropertyValue(u"ChainPrevName"_ustr, Any(*i));
2227
2228
0
            i = m_xImpl->m_xPrevFrmNames->erase(i);
2229
0
            j = m_xImpl->m_xNextFrmNames->erase(j);
2230
2231
            // There cannot be more than one previous frame
2232
0
            break;
2233
0
        }
2234
0
    }
2235
0
}
2236
2237
bool XMLTextImportHelper::IsInFrame() const
2238
1.57k
{
2239
1.57k
    static constexpr OUString s_TextFrame = u"TextFrame"_ustr;
2240
2241
1.57k
    bool bIsInFrame = false;
2242
2243
    // are we currently in a text frame? yes, if the cursor has a
2244
    // TextFrame property and it's non-NULL
2245
1.57k
    Reference<XPropertySet> xPropSet(const_cast<XMLTextImportHelper*>(this)->GetCursor(), UNO_QUERY);
2246
1.57k
    if (xPropSet.is())
2247
1.57k
    {
2248
1.57k
        if (xPropSet->getPropertySetInfo()->hasPropertyByName(s_TextFrame))
2249
1.57k
        {
2250
1.57k
            uno::Reference<XTextFrame> const xFrame(
2251
1.57k
                xPropSet->getPropertyValue(s_TextFrame), UNO_QUERY);
2252
2253
1.57k
            if (xFrame.is())
2254
0
            {
2255
0
                bIsInFrame = true;
2256
0
            }
2257
1.57k
        }
2258
1.57k
    }
2259
2260
1.57k
    return bIsInFrame;
2261
1.57k
}
2262
2263
bool XMLTextImportHelper::IsInHeaderFooter() const
2264
0
{
2265
0
    return false;
2266
0
}
2267
2268
Reference< XPropertySet> XMLTextImportHelper::createAndInsertOLEObject(
2269
                                        SvXMLImport&,
2270
                                        const OUString& /*rHRef*/,
2271
                                        const OUString& /*rStyleName*/,
2272
                                        const OUString& /*rTblName*/,
2273
                                        sal_Int32 /*nWidth*/, sal_Int32 /*nHeight*/ )
2274
0
{
2275
0
    Reference< XPropertySet> xPropSet;
2276
0
    return xPropSet;
2277
0
}
2278
2279
Reference< XPropertySet> XMLTextImportHelper::createAndInsertOOoLink(
2280
                                        SvXMLImport&,
2281
                                        const OUString& /*rHRef*/,
2282
                                        const OUString& /*rStyleName*/,
2283
                                        const OUString& /*rTblName*/,
2284
                                        sal_Int32 /*nWidth*/, sal_Int32 /*nHeight*/ )
2285
0
{
2286
0
    Reference< XPropertySet> xPropSet;
2287
0
    return xPropSet;
2288
0
}
2289
2290
Reference< XPropertySet> XMLTextImportHelper::createAndInsertApplet(
2291
                                        const OUString& /*rCode*/,
2292
                                        const OUString& /*rName*/,
2293
                                        bool /*bMayScript*/,
2294
                                        const OUString& /*rHRef*/,
2295
                                        sal_Int32 /*nWidth*/, sal_Int32 /*nHeight*/ )
2296
0
{
2297
0
    Reference< XPropertySet> xPropSet;
2298
0
    return xPropSet;
2299
0
}
2300
Reference< XPropertySet> XMLTextImportHelper::createAndInsertPlugin(
2301
                                        const OUString& /*rMimeType*/,
2302
                                        const OUString& /*rHRef*/,
2303
                                        sal_Int32 /*nWidth*/, sal_Int32 /*nHeight*/ )
2304
0
{
2305
0
    Reference< XPropertySet> xPropSet;
2306
0
    return xPropSet;
2307
0
}
2308
Reference< XPropertySet> XMLTextImportHelper::createAndInsertFloatingFrame(
2309
                                        const OUString& /*rName*/,
2310
                                        const OUString& /*rHRef*/,
2311
                                        const OUString& /*rStyleName*/,
2312
                                        sal_Int32 /*nWidth*/, sal_Int32 /*nHeight*/ )
2313
0
{
2314
0
    Reference< XPropertySet> xPropSet;
2315
0
    return xPropSet;
2316
0
}
2317
2318
void XMLTextImportHelper::endAppletOrPlugin(
2319
        const Reference < XPropertySet> &,
2320
        std::map < const OUString, OUString > &)
2321
0
{
2322
0
}
2323
// redline helper: dummy implementation to be overridden in sw/filter/xml
2324
void XMLTextImportHelper::RedlineAdd( const OUString& /*rType*/,
2325
                                      const OUString& /*rId*/,
2326
                                      const OUString& /*rAuthor*/,
2327
                                      const OUString& /*rComment*/,
2328
                                      const util::DateTime& /*rDateTime*/,
2329
                                      const OUString& /*rMovedID*/,
2330
                                      bool /*bMergeLastPara*/,
2331
                                      const OUString& /*rStyleName*/,
2332
                                      const OUString& /*rAutoName*/)
2333
0
{
2334
    // dummy implementation: do nothing
2335
0
}
2336
2337
Reference<XTextCursor> XMLTextImportHelper::RedlineCreateText(
2338
    Reference<XTextCursor> & /*rOldCursor*/,
2339
    const OUString& /*rId*/)
2340
0
{
2341
    // dummy implementation: do nothing
2342
0
    Reference<XTextCursor> xRet;
2343
0
    return xRet;
2344
0
}
2345
2346
void XMLTextImportHelper::RedlineSetCursor(
2347
    const OUString& /*rId*/,
2348
    bool /*bStart*/,
2349
    bool /*bIsOutsideOfParagraph*/)
2350
0
{
2351
    // dummy implementation: do nothing
2352
0
}
2353
2354
void XMLTextImportHelper::RedlineAdjustStartNodeCursor()
2355
0
{
2356
    // dummy implementation: do nothing
2357
0
}
2358
2359
void XMLTextImportHelper::SetShowChanges( bool )
2360
0
{
2361
    // dummy implementation: do nothing
2362
0
}
2363
2364
void XMLTextImportHelper::SetRecordChanges( bool )
2365
0
{
2366
    // dummy implementation: do nothing
2367
0
}
2368
void XMLTextImportHelper::SetChangesProtectionKey(const Sequence<sal_Int8> &)
2369
0
{
2370
    // dummy implementation: do nothing
2371
0
}
2372
2373
2374
OUString const & XMLTextImportHelper::GetOpenRedlineId() const
2375
21.6k
{
2376
21.6k
    return m_xImpl->m_sOpenRedlineIdentifier;
2377
21.6k
}
2378
2379
void XMLTextImportHelper::SetOpenRedlineId( OUString const & rId)
2380
0
{
2381
0
    m_xImpl->m_sOpenRedlineIdentifier = rId;
2382
0
}
2383
2384
void XMLTextImportHelper::ResetOpenRedlineId()
2385
0
{
2386
0
    SetOpenRedlineId(u""_ustr);
2387
0
}
2388
2389
void
2390
XMLTextImportHelper::SetCellParaStyleDefault(OUString const& rNewValue)
2391
13.9k
{
2392
13.9k
    m_xImpl->m_sCellParaStyleDefault = rNewValue;
2393
13.9k
}
2394
2395
OUString const& XMLTextImportHelper::GetCellParaStyleDefault() const
2396
235k
{
2397
235k
    return m_xImpl->m_sCellParaStyleDefault;
2398
235k
}
2399
2400
void XMLTextImportHelper::AddCrossRefHeadingMapping(OUString const& rFrom, OUString const& rTo)
2401
0
{
2402
0
    if (!m_xImpl->m_xCrossRefHeadingBookmarkMap)
2403
0
    {
2404
0
        m_xImpl->m_xCrossRefHeadingBookmarkMap.emplace();
2405
0
    }
2406
0
    m_xImpl->m_xCrossRefHeadingBookmarkMap->insert(std::make_pair(rFrom, rTo));
2407
0
}
2408
2409
// tdf#94804: hack to map cross reference fields that reference duplicate marks
2410
// note that we can't really check meta:generator for this since the file might
2411
// be round-tripped by different versions preserving duplicates => always map
2412
void XMLTextImportHelper::MapCrossRefHeadingFieldsHorribly()
2413
4.14k
{
2414
4.14k
    if (!m_xImpl->m_xCrossRefHeadingBookmarkMap)
2415
4.14k
    {
2416
4.14k
        return;
2417
4.14k
    }
2418
2419
0
    uno::Reference<text::XTextFieldsSupplier> const xFieldsSupplier(
2420
0
            m_xImpl->m_rSvXMLImport.GetModel(), uno::UNO_QUERY);
2421
0
    if (!xFieldsSupplier.is())
2422
0
    {
2423
0
        return;
2424
0
    }
2425
0
    uno::Reference<container::XEnumerationAccess> const xFieldsEA(
2426
0
            xFieldsSupplier->getTextFields());
2427
0
    uno::Reference<container::XEnumeration> const xFields(
2428
0
            xFieldsEA->createEnumeration());
2429
0
    while (xFields->hasMoreElements())
2430
0
    {
2431
0
        uno::Reference<lang::XServiceInfo> const xFieldInfo(
2432
0
                xFields->nextElement(), uno::UNO_QUERY);
2433
0
        if (!xFieldInfo->supportsService(u"com.sun.star.text.textfield.GetReference"_ustr))
2434
0
        {
2435
0
            continue;
2436
0
        }
2437
0
        uno::Reference<beans::XPropertySet> const xField(
2438
0
                xFieldInfo, uno::UNO_QUERY);
2439
0
        sal_uInt16 nType(0);
2440
0
        xField->getPropertyValue(u"ReferenceFieldSource"_ustr) >>= nType;
2441
0
        if (text::ReferenceFieldSource::BOOKMARK != nType)
2442
0
        {
2443
0
            continue;
2444
0
        }
2445
0
        OUString name;
2446
0
        xField->getPropertyValue(u"SourceName"_ustr) >>= name;
2447
0
        auto const iter(m_xImpl->m_xCrossRefHeadingBookmarkMap->find(name));
2448
0
        if (iter == m_xImpl->m_xCrossRefHeadingBookmarkMap->end())
2449
0
        {
2450
0
            continue;
2451
0
        }
2452
0
        xField->setPropertyValue(u"SourceName"_ustr, uno::Any(iter->second));
2453
0
    }
2454
0
}
2455
2456
void XMLTextImportHelper::setBookmarkAttributes(OUString const& bookmark, bool hidden, OUString const& condition)
2457
36
{
2458
36
    m_xImpl->m_bBookmarkHidden[bookmark] = hidden;
2459
36
    m_xImpl->m_sBookmarkCondition[bookmark] = condition;
2460
36
}
2461
2462
bool XMLTextImportHelper::getBookmarkHidden(OUString const& bookmark) const
2463
31
{
2464
31
    return m_xImpl->m_bBookmarkHidden[bookmark];
2465
31
}
2466
2467
const OUString& XMLTextImportHelper::getBookmarkCondition(OUString const& bookmark) const
2468
31
{
2469
31
    return m_xImpl->m_sBookmarkCondition[bookmark];
2470
31
}
2471
2472
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */