Avoid potential negative array index access to cached text.
[LibreOffice.git] / xmloff / source / text / XMLTextMasterPageContext.cxx
blob71e5f677018266fdc2cf094db01f5a6033e4c3fc
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
20 #include <sal/config.h>
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/namespacemap.hxx>
32 #include <xmloff/xmlnamespace.hxx>
33 #include <xmloff/prstylei.hxx>
34 #include <xmloff/xmltoken.hxx>
35 #include <xmloff/XMLTextMasterPageContext.hxx>
36 #include <XMLTextHeaderFooterContext.hxx>
37 #include <PageMasterImportContext.hxx>
38 #include <xmloff/xmlimp.hxx>
41 using namespace ::com::sun::star;
42 using namespace ::com::sun::star::uno;
43 using namespace ::com::sun::star::xml::sax;
44 using namespace ::com::sun::star::style;
45 using namespace ::com::sun::star::text;
46 using namespace ::com::sun::star::beans;
47 using namespace ::com::sun::star::container;
48 using namespace ::com::sun::star::lang;
49 using namespace ::xmloff::token;
51 Reference < XStyle > XMLTextMasterPageContext::Create()
53 Reference < XStyle > xNewStyle;
55 Reference< XMultiServiceFactory > xFactory( GetImport().GetModel(),
56 UNO_QUERY );
57 if( xFactory.is() )
59 Reference < XInterface > xIfc =
60 xFactory->createInstance("com.sun.star.style.PageStyle");
61 if( xIfc.is() )
62 xNewStyle.set( xIfc, UNO_QUERY );
65 return xNewStyle;
68 constexpr OUString gsFollowStyle( u"FollowStyle"_ustr );
70 XMLTextMasterPageContext::XMLTextMasterPageContext( SvXMLImport& rImport,
71 sal_Int32 /*nElement*/,
72 const Reference< XFastAttributeList > & xAttrList,
73 bool bOverwrite )
74 : SvXMLStyleContext( rImport, XmlStyleFamily::MASTER_PAGE )
75 , m_bInsertHeader( false )
76 , m_bInsertFooter( false )
77 , m_bInsertHeaderLeft( false )
78 , m_bInsertFooterLeft( false )
79 , m_bInsertHeaderFirst( false )
80 , m_bInsertFooterFirst( false )
81 , m_bHeaderInserted( false )
82 , m_bFooterInserted( false )
84 OUString sName, sDisplayName;
85 for (auto &aIter : sax_fastparser::castToFastAttributeList( xAttrList ))
87 const OUString aValue = aIter.toString();
88 switch (aIter.getToken())
90 case XML_ELEMENT(STYLE, XML_NAME):
91 sName = aValue;
92 break;
93 case XML_ELEMENT(STYLE, XML_DISPLAY_NAME):
94 sDisplayName = aValue;
95 break;
96 case XML_ELEMENT(STYLE, XML_NEXT_STYLE_NAME):
97 m_sFollow = aValue;
98 break;
99 case XML_ELEMENT(STYLE, XML_PAGE_LAYOUT_NAME):
100 m_sPageMasterName = aValue;
101 break;
102 case XML_ELEMENT(DRAW, XML_STYLE_NAME):
103 m_sDrawingPageStyle = aValue;
104 break;
105 default:
106 XMLOFF_WARN_UNKNOWN("xmloff", aIter);
110 if( !sDisplayName.isEmpty() )
112 rImport.AddStyleDisplayName( XmlStyleFamily::MASTER_PAGE, sName,
113 sDisplayName );
115 else
117 sDisplayName = sName;
120 if( sDisplayName.isEmpty() )
121 return;
123 Reference < XNameContainer > xPageStyles =
124 GetImport().GetTextImport()->GetPageStyles();
125 if( !xPageStyles.is() )
126 return;
128 Any aAny;
129 bool bNew = false;
130 if( xPageStyles->hasByName( sDisplayName ) )
132 aAny = xPageStyles->getByName( sDisplayName );
133 aAny >>= m_xStyle;
135 else
137 m_xStyle = Create();
138 if( !m_xStyle.is() )
139 return;
141 xPageStyles->insertByName( sDisplayName, Any(m_xStyle) );
142 bNew = true;
145 Reference < XPropertySet > xPropSet( m_xStyle, UNO_QUERY );
146 Reference< XPropertySetInfo > xPropSetInfo =
147 xPropSet->getPropertySetInfo();
148 OUString sIsPhysical( "IsPhysical" );
149 if( !bNew && xPropSetInfo->hasPropertyByName( sIsPhysical ) )
151 aAny = xPropSet->getPropertyValue( sIsPhysical );
152 bNew = !*o3tl::doAccess<bool>(aAny);
154 SetNew( bNew );
156 if( !(bOverwrite || bNew) )
157 return;
159 Reference < XMultiPropertyStates > xMultiStates( xPropSet,
160 UNO_QUERY );
161 OSL_ENSURE( xMultiStates.is(),
162 "text page style does not support multi property set" );
163 if( xMultiStates.is() )
164 xMultiStates->setAllPropertiesToDefault();
166 if ( xPropSetInfo->hasPropertyByName( "GridDisplay" ) )
167 xPropSet->setPropertyValue( "GridDisplay", Any(false) );
169 if ( xPropSetInfo->hasPropertyByName( "GridPrint" ) )
170 xPropSet->setPropertyValue( "GridPrint", Any(false) );
172 m_bInsertHeader = m_bInsertFooter = true;
173 m_bInsertHeaderLeft = m_bInsertFooterLeft = true;
174 m_bInsertHeaderFirst = m_bInsertFooterFirst = true;
177 XMLTextMasterPageContext::~XMLTextMasterPageContext()
181 css::uno::Reference< css::xml::sax::XFastContextHandler > XMLTextMasterPageContext::createFastChildContext(
182 sal_Int32 nElement,
183 const css::uno::Reference< css::xml::sax::XFastAttributeList >& xAttrList )
185 SvXMLImportContextRef xContext;
187 bool bInsert = false, bFooter = false, bLeft = false, bFirst = false;
188 switch( nElement )
190 case XML_ELEMENT(STYLE, XML_HEADER):
191 if( m_bInsertHeader && !m_bHeaderInserted )
193 bInsert = true;
194 m_bHeaderInserted = true;
196 break;
197 case XML_ELEMENT(STYLE, XML_FOOTER):
198 if( m_bInsertFooter && !m_bFooterInserted )
200 bInsert = bFooter = true;
201 m_bFooterInserted = true;
203 break;
204 case XML_ELEMENT(STYLE, XML_HEADER_LEFT):
205 if( m_bInsertHeaderLeft && m_bHeaderInserted )
206 bInsert = bLeft = true;
207 break;
208 case XML_ELEMENT(STYLE, XML_FOOTER_LEFT):
209 if( m_bInsertFooterLeft && m_bFooterInserted )
210 bInsert = bFooter = bLeft = true;
211 break;
212 case XML_ELEMENT(LO_EXT, XML_HEADER_FIRST):
213 case XML_ELEMENT(STYLE, XML_HEADER_FIRST):
214 if( m_bInsertHeaderFirst && m_bHeaderInserted )
215 bInsert = bFirst = true;
216 break;
217 case XML_ELEMENT(LO_EXT, XML_FOOTER_FIRST):
218 case XML_ELEMENT(STYLE, XML_FOOTER_FIRST):
219 if( m_bInsertFooterFirst && m_bFooterInserted )
220 bInsert = bFooter = bFirst = true;
221 break;
224 if( bInsert && m_xStyle.is() )
226 xContext = CreateHeaderFooterContext( nElement, xAttrList,
227 bFooter, bLeft, bFirst );
230 return xContext;
233 SvXMLImportContext *XMLTextMasterPageContext::CreateHeaderFooterContext(
234 sal_Int32 /*nElement*/,
235 const css::uno::Reference< css::xml::sax::XFastAttributeList > & /*xAttrList*/,
236 const bool bFooter,
237 const bool bLeft,
238 const bool bFirst )
240 Reference < XPropertySet > xPropSet( m_xStyle, UNO_QUERY );
241 return new XMLTextHeaderFooterContext( GetImport(), xPropSet, bFooter, bLeft, bFirst );
244 void XMLTextMasterPageContext::Finish( bool bOverwrite )
246 if( !(m_xStyle.is() && (IsNew() || bOverwrite)) )
247 return;
249 Reference < XPropertySet > xPropSet( m_xStyle, UNO_QUERY );
250 XMLPropStyleContext * pDrawingPageStyle(nullptr);
251 if (!m_sDrawingPageStyle.isEmpty())
253 pDrawingPageStyle = GetImport().GetTextImport()->FindDrawingPage(m_sDrawingPageStyle);
255 PageStyleContext * pPageLayout(nullptr);
256 if( !m_sPageMasterName.isEmpty() )
258 pPageLayout = static_cast<PageStyleContext *>(GetImport().GetTextImport()->FindPageMaster(m_sPageMasterName));
260 if (pPageLayout)
262 pPageLayout->FillPropertySet_PageStyle(xPropSet, pDrawingPageStyle);
264 else if (pDrawingPageStyle)
266 // don't need to care about old background attributes in this case
267 pDrawingPageStyle->FillPropertySet(xPropSet);
270 Reference < XNameContainer > xPageStyles =
271 GetImport().GetTextImport()->GetPageStyles();
272 if( !xPageStyles.is() )
273 return;
275 Reference< XPropertySetInfo > xPropSetInfo =
276 xPropSet->getPropertySetInfo();
277 if( xPropSetInfo->hasPropertyByName( gsFollowStyle ) )
279 OUString sDisplayFollow(
280 GetImport().GetStyleDisplayName(
281 XmlStyleFamily::MASTER_PAGE, m_sFollow ) );
282 if( sDisplayFollow.isEmpty() ||
283 !xPageStyles->hasByName( sDisplayFollow ) )
284 sDisplayFollow = m_xStyle->getName();
286 Any aAny = xPropSet->getPropertyValue( gsFollowStyle );
287 OUString sCurrFollow;
288 aAny >>= sCurrFollow;
289 if( sCurrFollow != sDisplayFollow )
291 xPropSet->setPropertyValue( gsFollowStyle, Any(sDisplayFollow) );
295 if ( xPropSetInfo->hasPropertyByName( "Hidden" ) )
297 xPropSet->setPropertyValue( "Hidden", uno::Any( IsHidden( ) ) );
301 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */