Coverage Report

Created: 2026-07-10 11:04

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libreoffice/xmloff/source/text/XMLTextMasterPageContext.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 <sal/config.h>
21
22
#include <com/sun/star/frame/XModel.hpp>
23
#include <com/sun/star/style/XStyle.hpp>
24
#include <com/sun/star/lang/XMultiServiceFactory.hpp>
25
#include <com/sun/star/beans/XMultiPropertyStates.hpp>
26
#include <com/sun/star/beans/XPropertySet.hpp>
27
#include <com/sun/star/container/XNameContainer.hpp>
28
#include <o3tl/any.hxx>
29
#include <sal/log.hxx>
30
#include <osl/diagnose.h>
31
#include <xmloff/xmlnamespace.hxx>
32
#include <xmloff/prstylei.hxx>
33
#include <xmloff/xmltoken.hxx>
34
#include <xmloff/XMLTextMasterPageContext.hxx>
35
#include <XMLTextHeaderFooterContext.hxx>
36
#include <PageMasterImportContext.hxx>
37
#include <xmloff/xmlimp.hxx>
38
39
40
using namespace ::com::sun::star;
41
using namespace ::com::sun::star::uno;
42
using namespace ::com::sun::star::xml::sax;
43
using namespace ::com::sun::star::style;
44
using namespace ::com::sun::star::text;
45
using namespace ::com::sun::star::beans;
46
using namespace ::com::sun::star::container;
47
using namespace ::com::sun::star::lang;
48
using namespace ::xmloff::token;
49
50
Reference < XStyle > XMLTextMasterPageContext::Create()
51
4.49k
{
52
4.49k
    Reference < XStyle > xNewStyle;
53
54
4.49k
    Reference< XMultiServiceFactory > xFactory( GetImport().GetModel(),
55
4.49k
                                                    UNO_QUERY );
56
4.49k
    if( xFactory.is() )
57
4.49k
    {
58
4.49k
        Reference < XInterface > xIfc =
59
4.49k
            xFactory->createInstance(u"com.sun.star.style.PageStyle"_ustr);
60
4.49k
        if( xIfc.is() )
61
4.49k
            xNewStyle.set( xIfc, UNO_QUERY );
62
4.49k
    }
63
64
4.49k
    return xNewStyle;
65
4.49k
}
66
67
constexpr OUString gsFollowStyle( u"FollowStyle"_ustr );
68
constexpr OUString gsHeaderNoFirst( u"HeaderNoFirst"_ustr );
69
constexpr OUString gsFooterNoFirst( u"FooterNoFirst"_ustr );
70
constexpr OUString gsFirstShareContent(u"FirstIsShared"_ustr);
71
72
XMLTextMasterPageContext::XMLTextMasterPageContext( SvXMLImport& rImport,
73
        sal_Int32 /*nElement*/,
74
        const Reference< XFastAttributeList > & xAttrList,
75
        bool bOverwrite )
76
38.1k
:   SvXMLStyleContext( rImport, XmlStyleFamily::MASTER_PAGE )
77
38.1k
,   m_bInsertHeader( false )
78
38.1k
,   m_bInsertFooter( false )
79
38.1k
,   m_bInsertHeaderLeft( false )
80
38.1k
,   m_bInsertFooterLeft( false )
81
38.1k
,   m_bInsertHeaderFirst( false )
82
38.1k
,   m_bInsertFooterFirst( false )
83
38.1k
,   m_bHeaderInserted( false )
84
38.1k
,   m_bFooterInserted( false )
85
38.1k
{
86
38.1k
    OUString sName, sDisplayName;
87
38.1k
    for (auto &aIter : sax_fastparser::castToFastAttributeList( xAttrList ))
88
76.8k
    {
89
76.8k
        const OUString aValue = aIter.toString();
90
76.8k
        switch (aIter.getToken())
91
76.8k
        {
92
34.8k
            case XML_ELEMENT(STYLE, XML_NAME):
93
34.8k
                sName = aValue;
94
34.8k
                break;
95
693
            case XML_ELEMENT(STYLE, XML_DISPLAY_NAME):
96
693
                sDisplayName = aValue;
97
693
                break;
98
473
            case XML_ELEMENT(STYLE, XML_NEXT_STYLE_NAME):
99
473
                m_sFollow = aValue;
100
473
                break;
101
29.6k
            case XML_ELEMENT(STYLE, XML_PAGE_LAYOUT_NAME):
102
29.6k
                m_sPageMasterName = aValue;
103
29.6k
                break;
104
0
            case XML_ELEMENT(STYLE, XML_IS_FIRST_PAGE_FOOTER_ENABLED):
105
0
            case XML_ELEMENT(LO_EXT, XML_IS_FIRST_PAGE_FOOTER_ENABLED):
106
0
            case XML_ELEMENT(COL_EXT, XML_IS_FIRST_PAGE_FOOTER_ENABLED):
107
0
                m_sIsFirstPageFooterEnabled = aValue;
108
0
                break;
109
0
            case XML_ELEMENT(STYLE, XML_IS_FIRST_PAGE_HEADER_ENABLED):
110
0
            case XML_ELEMENT(LO_EXT, XML_IS_FIRST_PAGE_HEADER_ENABLED):
111
0
            case XML_ELEMENT(COL_EXT, XML_IS_FIRST_PAGE_HEADER_ENABLED):
112
0
                m_sIsFirstPageHeaderEnabled = aValue;
113
0
                break;
114
10.9k
            case XML_ELEMENT(DRAW, XML_STYLE_NAME):
115
10.9k
                m_sDrawingPageStyle = aValue;
116
10.9k
                break;
117
175
            default:
118
175
                XMLOFF_WARN_UNKNOWN("xmloff", aIter);
119
76.8k
        }
120
76.8k
    }
121
122
38.1k
    if( !sDisplayName.isEmpty() )
123
693
    {
124
693
        rImport.AddStyleDisplayName( XmlStyleFamily::MASTER_PAGE, sName,
125
693
                                     sDisplayName );
126
693
    }
127
37.4k
    else
128
37.4k
    {
129
37.4k
        sDisplayName = sName;
130
37.4k
    }
131
132
38.1k
    if( sDisplayName.isEmpty() )
133
3.25k
        return;
134
135
34.9k
    Reference < XNameContainer > xPageStyles =
136
34.9k
            GetImport().GetTextImport()->GetPageStyles();
137
34.9k
    if( !xPageStyles.is() )
138
0
        return;
139
140
34.9k
    Any aAny;
141
34.9k
    bool bNew = false;
142
34.9k
    if( xPageStyles->hasByName( sDisplayName ) )
143
30.4k
    {
144
30.4k
        aAny = xPageStyles->getByName( sDisplayName );
145
30.4k
        aAny >>= m_xStyle;
146
30.4k
    }
147
4.49k
    else
148
4.49k
    {
149
4.49k
        m_xStyle = Create();
150
4.49k
        if( !m_xStyle.is() )
151
0
            return;
152
153
4.49k
        xPageStyles->insertByName( sDisplayName, Any(m_xStyle) );
154
4.49k
        bNew = true;
155
4.49k
    }
156
157
34.9k
    Reference < XPropertySet > xPropSet( m_xStyle, UNO_QUERY );
158
34.9k
    Reference< XPropertySetInfo > xPropSetInfo =
159
34.9k
                xPropSet->getPropertySetInfo();
160
34.9k
    OUString sIsPhysical( u"IsPhysical"_ustr );
161
34.9k
    if( !bNew && xPropSetInfo->hasPropertyByName( sIsPhysical ) )
162
17.9k
    {
163
17.9k
        aAny = xPropSet->getPropertyValue( sIsPhysical );
164
17.9k
        bNew = !*o3tl::doAccess<bool>(aAny);
165
17.9k
    }
166
34.9k
    SetNew( bNew );
167
168
34.9k
    if( !(bOverwrite || bNew) )
169
0
        return;
170
171
34.9k
    Reference < XMultiPropertyStates > xMultiStates( xPropSet,
172
34.9k
                                                     UNO_QUERY );
173
34.9k
    OSL_ENSURE( xMultiStates.is(),
174
34.9k
                "text page style does not support multi property set" );
175
34.9k
    if( xMultiStates.is() )
176
34.9k
        xMultiStates->setAllPropertiesToDefault();
177
178
34.9k
    if ( xPropSetInfo->hasPropertyByName( u"GridDisplay"_ustr ) )
179
20.7k
        xPropSet->setPropertyValue( u"GridDisplay"_ustr, Any(false) );
180
181
34.9k
    if ( xPropSetInfo->hasPropertyByName( u"GridPrint"_ustr ) )
182
20.7k
        xPropSet->setPropertyValue( u"GridPrint"_ustr, Any(false) );
183
184
34.9k
    m_bInsertHeader = m_bInsertFooter = true;
185
34.9k
    m_bInsertHeaderLeft = m_bInsertFooterLeft = true;
186
34.9k
    m_bInsertHeaderFirst = m_bInsertFooterFirst = true;
187
34.9k
}
188
189
XMLTextMasterPageContext::~XMLTextMasterPageContext()
190
38.1k
{
191
38.1k
}
192
193
css::uno::Reference< css::xml::sax::XFastContextHandler > XMLTextMasterPageContext::createFastChildContext(
194
    sal_Int32 nElement,
195
    const css::uno::Reference< css::xml::sax::XFastAttributeList >& xAttrList )
196
24.1k
{
197
24.1k
    SvXMLImportContextRef xContext;
198
199
24.1k
    bool bInsert = false, bFooter = false, bLeft = false, bFirst = false;
200
24.1k
    switch( nElement )
201
24.1k
    {
202
5.48k
    case XML_ELEMENT(STYLE, XML_HEADER):
203
5.48k
        if( m_bInsertHeader && !m_bHeaderInserted )
204
5.08k
        {
205
5.08k
            bInsert = true;
206
5.08k
            m_bHeaderInserted = true;
207
5.08k
        }
208
5.48k
        break;
209
2.48k
    case XML_ELEMENT(STYLE, XML_FOOTER):
210
2.48k
        if( m_bInsertFooter && !m_bFooterInserted )
211
1.82k
        {
212
1.82k
            bInsert = bFooter = true;
213
1.82k
            m_bFooterInserted = true;
214
1.82k
        }
215
2.48k
        break;
216
2.09k
    case XML_ELEMENT(STYLE, XML_HEADER_LEFT):
217
2.09k
        if( m_bInsertHeaderLeft && m_bHeaderInserted )
218
1.84k
            bInsert = bLeft = true;
219
2.09k
        break;
220
13.5k
    case XML_ELEMENT(STYLE, XML_FOOTER_LEFT):
221
13.5k
        if( m_bInsertFooterLeft && m_bFooterInserted )
222
13.0k
            bInsert = bFooter = bLeft = true;
223
13.5k
        break;
224
0
    case XML_ELEMENT(LO_EXT, XML_HEADER_FIRST):
225
0
    case XML_ELEMENT(STYLE, XML_HEADER_FIRST):
226
0
        if( m_bInsertHeaderFirst && m_bHeaderInserted )
227
0
            bInsert = bFirst = true;
228
0
        break;
229
0
    case XML_ELEMENT(LO_EXT, XML_FOOTER_FIRST):
230
0
    case XML_ELEMENT(STYLE, XML_FOOTER_FIRST):
231
0
        if( m_bInsertFooterFirst && m_bFooterInserted )
232
0
            bInsert = bFooter = bFirst = true;
233
0
        break;
234
24.1k
    }
235
236
24.1k
    if( bInsert && m_xStyle.is() )
237
21.8k
    {
238
21.8k
        xContext = CreateHeaderFooterContext( nElement, xAttrList,
239
21.8k
                                              bFooter, bLeft, bFirst );
240
21.8k
    }
241
242
24.1k
    return xContext;
243
24.1k
}
244
245
SvXMLImportContext *XMLTextMasterPageContext::CreateHeaderFooterContext(
246
            sal_Int32 /*nElement*/,
247
            const css::uno::Reference< css::xml::sax::XFastAttributeList > & /*xAttrList*/,
248
            const bool bFooter,
249
            const bool bLeft,
250
            const bool bFirst )
251
5.02k
{
252
5.02k
    Reference < XPropertySet > xPropSet( m_xStyle, UNO_QUERY );
253
5.02k
    return new XMLTextHeaderFooterContext( GetImport(), xPropSet, bFooter, bLeft, bFirst );
254
5.02k
}
255
256
void XMLTextMasterPageContext::Finish( bool bOverwrite )
257
26.6k
{
258
26.6k
    if( !(m_xStyle.is() && (IsNew() || bOverwrite)) )
259
2.43k
        return;
260
261
24.2k
    Reference < XPropertySet > xPropSet( m_xStyle, UNO_QUERY );
262
24.2k
    XMLPropStyleContext * pDrawingPageStyle(nullptr);
263
24.2k
    if (!m_sDrawingPageStyle.isEmpty())
264
6.73k
    {
265
6.73k
        pDrawingPageStyle = GetImport().GetTextImport()->FindDrawingPage(m_sDrawingPageStyle);
266
6.73k
    }
267
24.2k
    PageStyleContext * pPageLayout(nullptr);
268
24.2k
    if( !m_sPageMasterName.isEmpty() )
269
20.1k
    {
270
20.1k
        pPageLayout = static_cast<PageStyleContext *>(GetImport().GetTextImport()->FindPageMaster(m_sPageMasterName));
271
20.1k
    }
272
24.2k
    if (pPageLayout)
273
14.2k
    {
274
14.2k
        pPageLayout->FillPropertySet_PageStyle(xPropSet, pDrawingPageStyle);
275
14.2k
    }
276
9.95k
    else if (pDrawingPageStyle)
277
1.00k
    {
278
        // don't need to care about old background attributes in this case
279
1.00k
        pDrawingPageStyle->FillPropertySet(xPropSet);
280
1.00k
    }
281
282
24.2k
    Reference < XNameContainer > xPageStyles =
283
24.2k
        GetImport().GetTextImport()->GetPageStyles();
284
24.2k
    if( !xPageStyles.is() )
285
0
        return;
286
287
24.2k
    Reference< XPropertySetInfo > xPropSetInfo =
288
24.2k
        xPropSet->getPropertySetInfo();
289
24.2k
    if( xPropSetInfo->hasPropertyByName( gsFollowStyle ) )
290
13.2k
    {
291
13.2k
        OUString sDisplayFollow(
292
13.2k
            GetImport().GetStyleDisplayName(
293
13.2k
                    XmlStyleFamily::MASTER_PAGE, m_sFollow ) );
294
13.2k
        if( sDisplayFollow.isEmpty() ||
295
398
            !xPageStyles->hasByName( sDisplayFollow ) )
296
12.8k
            sDisplayFollow = m_xStyle->getName();
297
298
13.2k
        Any aAny = xPropSet->getPropertyValue( gsFollowStyle );
299
13.2k
        OUString sCurrFollow;
300
13.2k
        aAny >>= sCurrFollow;
301
13.2k
        if( sCurrFollow != sDisplayFollow )
302
253
        {
303
253
            xPropSet->setPropertyValue( gsFollowStyle, Any(sDisplayFollow) );
304
253
        }
305
13.2k
    }
306
307
24.2k
    if ( xPropSetInfo->hasPropertyByName( u"Hidden"_ustr ) )
308
24.2k
    {
309
24.2k
        xPropSet->setPropertyValue( u"Hidden"_ustr, uno::Any( IsHidden( ) ) );
310
24.2k
    }
311
24.2k
    if (xPropSetInfo->hasPropertyByName(gsHeaderNoFirst))
312
13.2k
    {
313
13.2k
        if (IsXMLToken(m_sIsFirstPageHeaderEnabled, XML_FALSE))
314
0
        {
315
0
            xPropSet->setPropertyValue( gsFirstShareContent, Any(false) );
316
0
            xPropSet->setPropertyValue( gsHeaderNoFirst, Any(true) );
317
0
        }
318
13.2k
        if (IsXMLToken(m_sIsFirstPageFooterEnabled, XML_FALSE))
319
0
        {
320
0
            xPropSet->setPropertyValue( gsFirstShareContent, Any(false) );
321
0
            xPropSet->setPropertyValue( gsFooterNoFirst, Any(true) );
322
0
        }
323
13.2k
    }
324
24.2k
}
325
326
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */