LibreOffice Module xmloff (master)  1
XMLFootnoteConfigurationImportContext.cxx
Go to the documentation of this file.
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 
22 
23 #include <rtl/ustring.hxx>
24 #include <rtl/ustrbuf.hxx>
25 
26 #include <sax/tools/converter.hxx>
27 
28 #include <xmloff/namespacemap.hxx>
29 #include <xmloff/xmlnamespace.hxx>
30 #include <xmloff/xmltoken.hxx>
31 #include <xmloff/xmlement.hxx>
32 
33 #include <xmloff/families.hxx>
34 #include <xmloff/xmluconv.hxx>
35 #include <xmloff/xmlimp.hxx>
36 #include <com/sun/star/frame/XModel.hpp>
37 #include <com/sun/star/xml/sax/XAttributeList.hpp>
38 #include <com/sun/star/beans/XPropertySet.hpp>
39 #include <com/sun/star/text/XFootnotesSupplier.hpp>
40 #include <com/sun/star/text/XEndnotesSupplier.hpp>
41 #include <com/sun/star/text/FootnoteNumbering.hpp>
42 #include <com/sun/star/style/NumberingType.hpp>
43 
44 
45 using namespace ::com::sun::star::text;
46 using namespace ::com::sun::star::beans;
47 using namespace ::com::sun::star::uno;
48 using namespace ::com::sun::star::style;
49 using namespace ::com::sun::star::xml::sax;
50 using namespace ::xmloff::token;
51 
52 
53 // XMLFootnoteConfigHelper
54 
55 namespace {
56 
58 class XMLFootnoteConfigHelper : public SvXMLImportContext
59 {
60  OUStringBuffer sBuffer;
62  bool bIsBegin;
63 
64 public:
65 
66  XMLFootnoteConfigHelper(
67  SvXMLImport& rImport,
68  sal_uInt16 nPrfx,
69  const OUString& rLName,
71  bool bBegin);
72 
73  virtual void EndElement() override;
74 
75  virtual void Characters( const OUString& rChars ) override;
76 };
77 
78 }
79 
80 XMLFootnoteConfigHelper::XMLFootnoteConfigHelper(
81  SvXMLImport& rImport,
82  sal_uInt16 nPrfx,
83  const OUString& rLName,
85  bool bBegin)
86 : SvXMLImportContext(rImport, nPrfx, rLName)
87 , sBuffer()
88 , rConfig(rConfigImport)
89 , bIsBegin(bBegin)
90 {
91 }
92 
93 void XMLFootnoteConfigHelper::EndElement()
94 {
95  if (bIsBegin)
96  {
97  rConfig.SetBeginNotice(sBuffer.makeStringAndClear());
98  }
99  else
100  {
101  rConfig.SetEndNotice(sBuffer.makeStringAndClear());
102  }
103 // rConfig = NULL; // import contexts are ref-counted
104 }
105 
106 void XMLFootnoteConfigHelper::Characters( const OUString& rChars )
107 {
108  sBuffer.append(rChars);
109 }
110 
111 
112 // XMLFootnoteConfigurationImportContext
113 
114 const OUStringLiteral gsPropertyAnchorCharStyleName("AnchorCharStyleName");
115 const OUStringLiteral gsPropertyCharStyleName("CharStyleName");
116 const OUStringLiteral gsPropertyNumberingType("NumberingType");
117 const OUStringLiteral gsPropertyPageStyleName("PageStyleName");
118 const OUStringLiteral gsPropertyParagraphStyleName("ParaStyleName");
119 const OUStringLiteral gsPropertyPrefix("Prefix");
120 const OUStringLiteral gsPropertyStartAt("StartAt");
121 const OUStringLiteral gsPropertySuffix("Suffix");
122 const OUStringLiteral gsPropertyPositionEndOfDoc("PositionEndOfDoc");
123 const OUStringLiteral gsPropertyFootnoteCounting("FootnoteCounting");
124 const OUStringLiteral gsPropertyEndNotice("EndNotice");
125 const OUStringLiteral gsPropertyBeginNotice("BeginNotice");
126 
128  SvXMLImport& rImport,
129  sal_uInt16 nPrfx,
130  const OUString& rLocalName,
131  const Reference<XAttributeList> & xAttrList)
132 : SvXMLStyleContext(rImport, nPrfx, rLocalName, xAttrList, XmlStyleFamily::TEXT_FOOTNOTECONFIG)
133 , sNumFormat("1")
134 , sNumSync("false")
135 , nOffset(0)
136 , nNumbering(FootnoteNumbering::PER_PAGE)
137 , bPosition(false)
138 , bIsEndnote(false)
139 {
140  sal_Int16 nLength = xAttrList->getLength();
141  for(sal_Int16 nAttr = 0; nAttr < nLength; nAttr++)
142  {
143  OUString sLocalName;
144  sal_uInt16 nPrefix = GetImport().GetNamespaceMap().
145  GetKeyByAttrName( xAttrList->getNameByIndex(nAttr),
146  &sLocalName );
147  if( XML_NAMESPACE_TEXT == nPrefix && IsXMLToken( sLocalName,
148  XML_NOTE_CLASS ) )
149  {
150  const OUString& rValue = xAttrList->getValueByIndex( nAttr );
151  if( IsXMLToken( rValue, XML_ENDNOTE ) )
152  {
153  bIsEndnote = true;
155  }
156  break;
157  }
158  }
159 
160 }
162 {
163 }
164 
165 namespace {
166 
168 {
169  XML_TOK_FTNCONFIG_CITATION_STYLENAME,
170  XML_TOK_FTNCONFIG_ANCHOR_STYLENAME,
171  XML_TOK_FTNCONFIG_DEFAULT_STYLENAME,
172  XML_TOK_FTNCONFIG_PAGE_STYLENAME,
173  XML_TOK_FTNCONFIG_OFFSET,
174  XML_TOK_FTNCONFIG_NUM_PREFIX,
175  XML_TOK_FTNCONFIG_NUM_SUFFIX,
176  XML_TOK_FTNCONFIG_NUM_FORMAT,
177  XML_TOK_FTNCONFIG_NUM_SYNC,
178  XML_TOK_FTNCONFIG_START_AT,
179  XML_TOK_FTNCONFIG_POSITION
180 };
181 
182 }
183 
185 {
186  { XML_NAMESPACE_TEXT, XML_CITATION_STYLE_NAME, XML_TOK_FTNCONFIG_CITATION_STYLENAME },
187  { XML_NAMESPACE_TEXT, XML_CITATION_BODY_STYLE_NAME, XML_TOK_FTNCONFIG_ANCHOR_STYLENAME },
188  { XML_NAMESPACE_TEXT, XML_DEFAULT_STYLE_NAME, XML_TOK_FTNCONFIG_DEFAULT_STYLENAME },
189  { XML_NAMESPACE_TEXT, XML_MASTER_PAGE_NAME, XML_TOK_FTNCONFIG_PAGE_STYLENAME },
190  { XML_NAMESPACE_TEXT, XML_START_VALUE, XML_TOK_FTNCONFIG_OFFSET },
191  { XML_NAMESPACE_STYLE, XML_NUM_PREFIX, XML_TOK_FTNCONFIG_NUM_PREFIX },
192  { XML_NAMESPACE_STYLE, XML_NUM_SUFFIX, XML_TOK_FTNCONFIG_NUM_SUFFIX },
193  { XML_NAMESPACE_STYLE, XML_NUM_FORMAT, XML_TOK_FTNCONFIG_NUM_FORMAT },
194  { XML_NAMESPACE_STYLE, XML_NUM_LETTER_SYNC, XML_TOK_FTNCONFIG_NUM_SYNC },
195  { XML_NAMESPACE_TEXT, XML_START_NUMBERING_AT, XML_TOK_FTNCONFIG_START_AT},
196  { XML_NAMESPACE_TEXT, XML_FOOTNOTES_POSITION, XML_TOK_FTNCONFIG_POSITION},
197 
198  // for backwards compatibility with SRC630 & earlier
199  { XML_NAMESPACE_TEXT, XML_NUM_PREFIX, XML_TOK_FTNCONFIG_NUM_PREFIX },
200  { XML_NAMESPACE_TEXT, XML_NUM_SUFFIX, XML_TOK_FTNCONFIG_NUM_SUFFIX },
201  { XML_NAMESPACE_TEXT, XML_OFFSET, XML_TOK_FTNCONFIG_OFFSET },
203 };
204 
205 const SvXMLTokenMap&
207 {
208  if (!pAttrTokenMap)
209  {
210  pAttrTokenMap.reset( new SvXMLTokenMap(aTextFieldAttrTokenMap) );
211  }
212 
213  return *pAttrTokenMap;
214 }
215 
217 {
218  { XML_PAGE, FootnoteNumbering::PER_PAGE },
219  { XML_CHAPTER, FootnoteNumbering::PER_CHAPTER },
220  { XML_DOCUMENT, FootnoteNumbering::PER_DOCUMENT },
221  { XML_TOKEN_INVALID, 0 },
222 };
223 
225  const OUString& rLocalName,
226  const OUString& rValue )
227 {
228  switch (GetFtnConfigAttrTokenMap().Get(nPrefixKey, rLocalName))
229  {
230  case XML_TOK_FTNCONFIG_CITATION_STYLENAME:
232  break;
233  case XML_TOK_FTNCONFIG_ANCHOR_STYLENAME:
235  break;
236  case XML_TOK_FTNCONFIG_DEFAULT_STYLENAME:
238  break;
239  case XML_TOK_FTNCONFIG_PAGE_STYLENAME:
240  sPageStyle = rValue;
241  break;
242  case XML_TOK_FTNCONFIG_OFFSET:
243  {
244  sal_Int32 nTmp;
245  if (::sax::Converter::convertNumber(nTmp, rValue))
246  {
247  nOffset = static_cast<sal_uInt16>(nTmp);
248  }
249  break;
250  }
251  case XML_TOK_FTNCONFIG_NUM_PREFIX:
252  sPrefix = rValue;
253  break;
254  case XML_TOK_FTNCONFIG_NUM_SUFFIX:
255  sSuffix = rValue;
256  break;
257  case XML_TOK_FTNCONFIG_NUM_FORMAT:
258  sNumFormat = rValue;
259  break;
260  case XML_TOK_FTNCONFIG_NUM_SYNC:
261  sNumSync = rValue;
262  break;
263  case XML_TOK_FTNCONFIG_START_AT:
264  {
266  aFootnoteNumberingMap);
267  break;
268  }
269  case XML_TOK_FTNCONFIG_POSITION:
270  bPosition = IsXMLToken( rValue, XML_DOCUMENT );
271  break;
272  default:
273  ; // ignore
274  }
275 }
276 
278  sal_uInt16 nPrefix,
279  const OUString& rLocalName,
280  const Reference<XAttributeList> & xAttrList )
281 {
282  SvXMLImportContextRef xContext;
283 
284  if (!bIsEndnote)
285  {
286  if (XML_NAMESPACE_TEXT == nPrefix)
287  {
288  if ( IsXMLToken( rLocalName,
290  {
291  xContext = new XMLFootnoteConfigHelper(GetImport(),
292  nPrefix, rLocalName,
293  *this, false);
294  }
295  else if ( IsXMLToken( rLocalName,
297  {
298  xContext = new XMLFootnoteConfigHelper(GetImport(),
299  nPrefix, rLocalName,
300  *this, true);
301  }
302  // else: default context
303  }
304  // else: unknown namespace -> default context
305  }
306  // else: endnote -> default context
307 
308  if (!xContext)
309  {
310  // default: delegate to super class
311  xContext = SvXMLStyleContext::CreateChildContext(nPrefix,
312  rLocalName,
313  xAttrList);
314  }
315 
316  return xContext;
317 }
318 
319 // Rename method <CreateAndInsertLate(..)> to <Finish(..)> (#i40597#)
321 {
322 
323  if (!bOverwrite)
324  return;
325 
326  if (bIsEndnote)
327  {
328  Reference<XEndnotesSupplier> xSupplier(
329  GetImport().GetModel(), UNO_QUERY);
330  if (xSupplier.is())
331  {
332  ProcessSettings(xSupplier->getEndnoteSettings());
333  }
334  }
335  else
336  {
337  Reference<XFootnotesSupplier> xSupplier(
338  GetImport().GetModel(), UNO_QUERY);
339  if (xSupplier.is())
340  {
341  ProcessSettings(xSupplier->getFootnoteSettings());
342  }
343  }
344  // else: ignore (there's only one configuration, so we can only overwrite)
345 }
346 
348  const Reference<XPropertySet> & rConfig)
349 {
350  Any aAny;
351 
352  if (!sCitationStyle.isEmpty())
353  {
354  aAny <<= GetImport().GetStyleDisplayName(
356  rConfig->setPropertyValue(gsPropertyCharStyleName, aAny);
357  }
358 
359  if (!sAnchorStyle.isEmpty())
360  {
361  aAny <<= GetImport().GetStyleDisplayName(
363  rConfig->setPropertyValue(gsPropertyAnchorCharStyleName, aAny);
364  }
365 
366  if (!sPageStyle.isEmpty())
367  {
368  aAny <<= GetImport().GetStyleDisplayName(
370  rConfig->setPropertyValue(gsPropertyPageStyleName, aAny);
371  }
372 
373  if (!sDefaultStyle.isEmpty())
374  {
375  aAny <<= GetImport().GetStyleDisplayName(
377  rConfig->setPropertyValue(gsPropertyParagraphStyleName, aAny);
378  }
379 
380  rConfig->setPropertyValue(gsPropertyPrefix, Any(sPrefix));
381 
382  rConfig->setPropertyValue(gsPropertySuffix, Any(sSuffix));
383 
384  sal_Int16 nNumType = NumberingType::ARABIC;
386  sNumSync );
387  // #i61399: Corrupt file? It contains "Bullet" as numbering style for footnotes.
388  // Okay, even it seems to be corrupt, we will oversee this and set the style to ARABIC
389  if( NumberingType::CHAR_SPECIAL == nNumType )
390  nNumType = NumberingType::ARABIC;
391 
392  rConfig->setPropertyValue(gsPropertyNumberingType, Any(nNumType));
393 
394  rConfig->setPropertyValue(gsPropertyStartAt, Any(nOffset));
395 
396  if (!bIsEndnote)
397  {
398  rConfig->setPropertyValue(gsPropertyPositionEndOfDoc, Any(bPosition));
399  rConfig->setPropertyValue(gsPropertyFootnoteCounting, Any(nNumbering));
400  rConfig->setPropertyValue(gsPropertyEndNotice, Any(sEndNotice));
401  rConfig->setPropertyValue(gsPropertyBeginNotice, Any(sBeginNotice));
402  }
403 }
404 
406  const OUString& sText)
407 {
408  sBeginNotice = sText;
409 }
410 
412  const OUString& sText)
413 {
414  sEndNotice = sText;
415 }
416 
417 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
bool IsXMLToken(const OUString &rString, enum XMLTokenEnum eToken)
compare eToken to the string
Definition: xmltoken.cxx:3428
const OUStringLiteral gsPropertyStartAt("StartAt")
static bool convertEnum(EnumT &rEnum, const OUString &rValue, const SvXMLEnumMapEntry< EnumT > *pMap)
convert string to enum using given enum map, if the enum is not found in the map, this method will re...
Definition: xmluconv.hxx:128
virtual void EndElement()
EndElement is called before a context will be destructed, but after an elements context has been pars...
Definition: xmlictxt.cxx:62
bool convertNumFormat(sal_Int16 &rType, const OUString &rNumFormat, const OUString &rNumLetterSync, bool bNumberNone=false) const
convert num-format and num-letter-sync values to NumberingType
Definition: xmluconv.cxx:574
SvXMLImport & GetImport()
Definition: xmlictxt.hxx:62
SvXMLNamespaceMap & GetNamespaceMap()
Definition: xmlimp.hxx:401
const SvXMLTokenMap & GetFtnConfigAttrTokenMap()
get token map for attributes
const OUStringLiteral gsPropertyBeginNotice("BeginNotice")
const OUStringLiteral gsPropertyAnchorCharStyleName("AnchorCharStyleName")
const OUStringLiteral gsPropertyPageStyleName("PageStyleName")
#define XML_TOKEN_MAP_END
Definition: xmltkmap.hxx:33
virtual void Characters(const OUString &rChars)
This method is called for all characters that are contained in the current element.
Definition: xmlictxt.cxx:66
css::uno::Any const & rValue
Definition: ImageStyle.hxx:38
XmlStyleFamily
Definition: families.hxx:47
const OUStringLiteral gsPropertyFootnoteCounting("FootnoteCounting")
const OUStringLiteral gsPropertyEndNotice("EndNotice")
sal_Int16 nNumType
SvXMLEnumMapEntry< sal_Int16 > const aFootnoteNumberingMap[]
const OUStringLiteral gsPropertyParagraphStyleName("ParaStyleName")
virtual void SetAttribute(sal_uInt16 nPrefixKey, const OUString &rLocalName, const OUString &rValue) override
parse attributes
void ProcessSettings(const css::uno::Reference< css::beans::XPropertySet > &rConfig)
set configuration at document
virtual void Finish(bool bOverwrite) override
set configuration at document; calls ProcessSettings
constexpr sal_uInt16 XML_NAMESPACE_TEXT
void SetFamily(XmlStyleFamily nSet)
Definition: xmlstyle.hxx:83
const OUStringLiteral gsPropertySuffix("Suffix")
import footnote and endnote configuration elements
virtual SvXMLImportContextRef CreateChildContext(sal_uInt16 nPrefix, const OUString &rLocalName, const css::uno::Reference< css::xml::sax::XAttributeList > &xAttrList) override
for footnotes, also parse begin and end notices
const OUStringLiteral gsPropertyPositionEndOfDoc("PositionEndOfDoc")
This class deliberately does not support XWeak, to improve performance when loading large documents...
Definition: xmlictxt.hxx:44
Map an XMLTokenEnum to an enum value.
Definition: ximpshap.hxx:40
OUString GetStyleDisplayName(XmlStyleFamily nFamily, const OUString &rName) const
Definition: xmlimp.cxx:1505
Handling of tokens in XML:
const OUStringLiteral gsPropertyPrefix("Prefix")
const SvXMLUnitConverter & GetMM100UnitConverter() const
Definition: xmlimp.hxx:403
void SetBeginNotice(const OUString &sText)
for helper class: set begin notice
const SvXMLTokenMapEntry aTextFieldAttrTokenMap[]
virtual SvXMLImportContextRef CreateChildContext(sal_uInt16 nPrefix, const OUString &rLocalName, const css::uno::Reference< css::xml::sax::XAttributeList > &xAttrList)
Create a children element context.
Definition: xmlictxt.cxx:51
void SetEndNotice(const OUString &sText)
for helper class: set end notice
SVXCORE_DLLPUBLIC MSO_SPT Get(const OUString &)
sal_Int32 nLength
Definition: xmltoken.cxx:36
const OUStringLiteral gsPropertyCharStyleName("CharStyleName")
constexpr sal_uInt16 XML_NAMESPACE_STYLE
const OUStringLiteral gsPropertyNumberingType("NumberingType")
static bool convertNumber(sal_Int32 &rValue, std::u16string_view aString, sal_Int32 nMin=SAL_MIN_INT32, sal_Int32 nMax=SAL_MAX_INT32)
XMLFootnoteConfigurationImportContext(SvXMLImport &rImport, sal_uInt16 nPrfx, const OUString &rLName, const css::uno::Reference< css::xml::sax::XAttributeList > &xAttrList)
typedef void(CALLTYPE *GetFuncDataPtr)(sal_uInt16 &nNo