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,
69  bool bBegin);
70 
71  virtual void SAL_CALL startFastElement( sal_Int32 /*nElement*/,
72  const css::uno::Reference< css::xml::sax::XFastAttributeList >& ) override {}
73  virtual void SAL_CALL endFastElement(sal_Int32 nElement) override;
74 
75  virtual void SAL_CALL characters( const OUString& rChars ) override;
76 };
77 
78 }
79 
80 XMLFootnoteConfigHelper::XMLFootnoteConfigHelper(
81  SvXMLImport& rImport,
83  bool bBegin)
84 : SvXMLImportContext(rImport)
85 , sBuffer()
86 , rConfig(rConfigImport)
87 , bIsBegin(bBegin)
88 {
89 }
90 
91 void XMLFootnoteConfigHelper::endFastElement(sal_Int32 )
92 {
93  if (bIsBegin)
94  {
95  rConfig.SetBeginNotice(sBuffer.makeStringAndClear());
96  }
97  else
98  {
99  rConfig.SetEndNotice(sBuffer.makeStringAndClear());
100  }
101 // rConfig = NULL; // import contexts are ref-counted
102 }
103 
104 void XMLFootnoteConfigHelper::characters( const OUString& rChars )
105 {
106  sBuffer.append(rChars);
107 }
108 
109 
110 // XMLFootnoteConfigurationImportContext
111 
112 constexpr OUStringLiteral gsPropertyAnchorCharStyleName(u"AnchorCharStyleName");
113 constexpr OUStringLiteral gsPropertyCharStyleName(u"CharStyleName");
114 constexpr OUStringLiteral gsPropertyNumberingType(u"NumberingType");
115 constexpr OUStringLiteral gsPropertyPageStyleName(u"PageStyleName");
116 constexpr OUStringLiteral gsPropertyParagraphStyleName(u"ParaStyleName");
117 constexpr OUStringLiteral gsPropertyPrefix(u"Prefix");
118 constexpr OUStringLiteral gsPropertyStartAt(u"StartAt");
119 constexpr OUStringLiteral gsPropertySuffix(u"Suffix");
120 constexpr OUStringLiteral gsPropertyPositionEndOfDoc(u"PositionEndOfDoc");
121 constexpr OUStringLiteral gsPropertyFootnoteCounting(u"FootnoteCounting");
122 constexpr OUStringLiteral gsPropertyEndNotice(u"EndNotice");
123 constexpr OUStringLiteral gsPropertyBeginNotice(u"BeginNotice");
124 
126  SvXMLImport& rImport,
127  sal_Int32 /*nElement*/,
128  const Reference<XFastAttributeList> & xAttrList)
130 , sNumFormat("1")
131 , sNumSync("false")
132 , nOffset(0)
133 , nNumbering(FootnoteNumbering::PER_PAGE)
134 , bPosition(false)
135 , bIsEndnote(false)
136 {
137  for (auto &aIter : sax_fastparser::castToFastAttributeList( xAttrList ))
138  {
139  if( aIter.getToken() == XML_ELEMENT(TEXT, XML_NOTE_CLASS) )
140  {
141  if( IsXMLToken(aIter.toString(), XML_ENDNOTE ) )
142  {
143  bIsEndnote = true;
145  }
146  break;
147  }
148  }
149 
150 }
152 {
153 }
154 
155 namespace {
156 
158 {
159  XML_TOK_FTNCONFIG_CITATION_STYLENAME,
160  XML_TOK_FTNCONFIG_ANCHOR_STYLENAME,
161  XML_TOK_FTNCONFIG_DEFAULT_STYLENAME,
162  XML_TOK_FTNCONFIG_PAGE_STYLENAME,
163  XML_TOK_FTNCONFIG_OFFSET,
164  XML_TOK_FTNCONFIG_NUM_PREFIX,
165  XML_TOK_FTNCONFIG_NUM_SUFFIX,
166  XML_TOK_FTNCONFIG_NUM_FORMAT,
167  XML_TOK_FTNCONFIG_NUM_SYNC,
168  XML_TOK_FTNCONFIG_START_AT,
169  XML_TOK_FTNCONFIG_POSITION
170 };
171 
172 }
173 
175 {
176  { XML_NAMESPACE_TEXT, XML_CITATION_STYLE_NAME, XML_TOK_FTNCONFIG_CITATION_STYLENAME },
177  { XML_NAMESPACE_TEXT, XML_CITATION_BODY_STYLE_NAME, XML_TOK_FTNCONFIG_ANCHOR_STYLENAME },
178  { XML_NAMESPACE_TEXT, XML_DEFAULT_STYLE_NAME, XML_TOK_FTNCONFIG_DEFAULT_STYLENAME },
179  { XML_NAMESPACE_TEXT, XML_MASTER_PAGE_NAME, XML_TOK_FTNCONFIG_PAGE_STYLENAME },
180  { XML_NAMESPACE_TEXT, XML_START_VALUE, XML_TOK_FTNCONFIG_OFFSET },
181  { XML_NAMESPACE_STYLE, XML_NUM_PREFIX, XML_TOK_FTNCONFIG_NUM_PREFIX },
182  { XML_NAMESPACE_STYLE, XML_NUM_SUFFIX, XML_TOK_FTNCONFIG_NUM_SUFFIX },
183  { XML_NAMESPACE_STYLE, XML_NUM_FORMAT, XML_TOK_FTNCONFIG_NUM_FORMAT },
184  { XML_NAMESPACE_STYLE, XML_NUM_LETTER_SYNC, XML_TOK_FTNCONFIG_NUM_SYNC },
185  { XML_NAMESPACE_TEXT, XML_START_NUMBERING_AT, XML_TOK_FTNCONFIG_START_AT},
186  { XML_NAMESPACE_TEXT, XML_FOOTNOTES_POSITION, XML_TOK_FTNCONFIG_POSITION},
187 
188  // for backwards compatibility with SRC630 & earlier
189  { XML_NAMESPACE_TEXT, XML_NUM_PREFIX, XML_TOK_FTNCONFIG_NUM_PREFIX },
190  { XML_NAMESPACE_TEXT, XML_NUM_SUFFIX, XML_TOK_FTNCONFIG_NUM_SUFFIX },
191  { XML_NAMESPACE_TEXT, XML_OFFSET, XML_TOK_FTNCONFIG_OFFSET },
193 };
194 
195 const SvXMLTokenMap&
197 {
198  if (!pAttrTokenMap)
199  {
200  pAttrTokenMap.reset( new SvXMLTokenMap(aTextFieldAttrTokenMap) );
201  }
202 
203  return *pAttrTokenMap;
204 }
205 
207 {
208  { XML_PAGE, FootnoteNumbering::PER_PAGE },
209  { XML_CHAPTER, FootnoteNumbering::PER_CHAPTER },
210  { XML_DOCUMENT, FootnoteNumbering::PER_DOCUMENT },
211  { XML_TOKEN_INVALID, 0 },
212 };
213 
215  const OUString& rLocalName,
216  const OUString& rValue )
217 {
218  switch (GetFtnConfigAttrTokenMap().Get(nPrefixKey, rLocalName))
219  {
220  case XML_TOK_FTNCONFIG_CITATION_STYLENAME:
222  break;
223  case XML_TOK_FTNCONFIG_ANCHOR_STYLENAME:
225  break;
226  case XML_TOK_FTNCONFIG_DEFAULT_STYLENAME:
228  break;
229  case XML_TOK_FTNCONFIG_PAGE_STYLENAME:
230  sPageStyle = rValue;
231  break;
232  case XML_TOK_FTNCONFIG_OFFSET:
233  {
234  sal_Int32 nTmp;
235  if (::sax::Converter::convertNumber(nTmp, rValue))
236  {
237  nOffset = static_cast<sal_uInt16>(nTmp);
238  }
239  break;
240  }
241  case XML_TOK_FTNCONFIG_NUM_PREFIX:
242  sPrefix = rValue;
243  break;
244  case XML_TOK_FTNCONFIG_NUM_SUFFIX:
245  sSuffix = rValue;
246  break;
247  case XML_TOK_FTNCONFIG_NUM_FORMAT:
248  sNumFormat = rValue;
249  break;
250  case XML_TOK_FTNCONFIG_NUM_SYNC:
251  sNumSync = rValue;
252  break;
253  case XML_TOK_FTNCONFIG_START_AT:
254  {
256  aFootnoteNumberingMap);
257  break;
258  }
259  case XML_TOK_FTNCONFIG_POSITION:
260  bPosition = IsXMLToken( rValue, XML_DOCUMENT );
261  break;
262  default:
263  ; // ignore
264  }
265 }
266 
267 css::uno::Reference< css::xml::sax::XFastContextHandler > XMLFootnoteConfigurationImportContext::createFastChildContext(
268  sal_Int32 nElement,
269  const css::uno::Reference< css::xml::sax::XFastAttributeList >& )
270 {
271  css::uno::Reference< css::xml::sax::XFastContextHandler > xContext;
272 
273  if (bIsEndnote)
274  return nullptr;
275 
276  switch (nElement)
277  {
279  xContext = new XMLFootnoteConfigHelper(GetImport(), *this, false);
280  break;
282  xContext = new XMLFootnoteConfigHelper(GetImport(), *this, true);
283  break;
284  }
285 
286  return xContext;
287 }
288 
289 // Rename method <CreateAndInsertLate(..)> to <Finish(..)> (#i40597#)
291 {
292 
293  if (!bOverwrite)
294  return;
295 
296  if (bIsEndnote)
297  {
298  Reference<XEndnotesSupplier> xSupplier(
299  GetImport().GetModel(), UNO_QUERY);
300  if (xSupplier.is())
301  {
302  ProcessSettings(xSupplier->getEndnoteSettings());
303  }
304  }
305  else
306  {
307  Reference<XFootnotesSupplier> xSupplier(
308  GetImport().GetModel(), UNO_QUERY);
309  if (xSupplier.is())
310  {
311  ProcessSettings(xSupplier->getFootnoteSettings());
312  }
313  }
314  // else: ignore (there's only one configuration, so we can only overwrite)
315 }
316 
318  const Reference<XPropertySet> & rConfig)
319 {
320  Any aAny;
321 
322  if (!sCitationStyle.isEmpty())
323  {
324  aAny <<= GetImport().GetStyleDisplayName(
326  rConfig->setPropertyValue(gsPropertyCharStyleName, aAny);
327  }
328 
329  if (!sAnchorStyle.isEmpty())
330  {
331  aAny <<= GetImport().GetStyleDisplayName(
333  rConfig->setPropertyValue(gsPropertyAnchorCharStyleName, aAny);
334  }
335 
336  if (!sPageStyle.isEmpty())
337  {
338  aAny <<= GetImport().GetStyleDisplayName(
340  rConfig->setPropertyValue(gsPropertyPageStyleName, aAny);
341  }
342 
343  if (!sDefaultStyle.isEmpty())
344  {
345  aAny <<= GetImport().GetStyleDisplayName(
347  rConfig->setPropertyValue(gsPropertyParagraphStyleName, aAny);
348  }
349 
350  rConfig->setPropertyValue(gsPropertyPrefix, Any(sPrefix));
351 
352  rConfig->setPropertyValue(gsPropertySuffix, Any(sSuffix));
353 
354  sal_Int16 nNumType = NumberingType::ARABIC;
356  sNumSync );
357  // #i61399: Corrupt file? It contains "Bullet" as numbering style for footnotes.
358  // Okay, even it seems to be corrupt, we will oversee this and set the style to ARABIC
359  if( NumberingType::CHAR_SPECIAL == nNumType )
360  nNumType = NumberingType::ARABIC;
361 
362  rConfig->setPropertyValue(gsPropertyNumberingType, Any(nNumType));
363 
364  rConfig->setPropertyValue(gsPropertyStartAt, Any(nOffset));
365 
366  if (!bIsEndnote)
367  {
368  rConfig->setPropertyValue(gsPropertyPositionEndOfDoc, Any(bPosition));
369  rConfig->setPropertyValue(gsPropertyFootnoteCounting, Any(nNumbering));
370  rConfig->setPropertyValue(gsPropertyEndNotice, Any(sEndNotice));
371  rConfig->setPropertyValue(gsPropertyBeginNotice, Any(sBeginNotice));
372  }
373 }
374 
376  const OUString& sText)
377 {
378  sBeginNotice = sText;
379 }
380 
382  const OUString& sText)
383 {
384  sEndNotice = sText;
385 }
386 
387 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
bool IsXMLToken(const OUString &rString, enum XMLTokenEnum eToken)
compare eToken to the string
Definition: xmltoken.cxx:3434
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
constexpr OUStringLiteral gsPropertyNumberingType(u"NumberingType")
constexpr OUStringLiteral gsPropertyCharStyleName(u"CharStyleName")
constexpr OUStringLiteral gsPropertyFootnoteCounting(u"FootnoteCounting")
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
virtual void SAL_CALL startFastElement(sal_Int32 Element, const css::uno::Reference< css::xml::sax::XFastAttributeList > &Attribs) override
Definition: xmlictxt.cxx:71
SvXMLImport & GetImport()
Definition: xmlictxt.hxx:62
FastAttributeList & castToFastAttributeList(const css::uno::Reference< css::xml::sax::XFastAttributeList > &xAttrList)
const SvXMLTokenMap & GetFtnConfigAttrTokenMap()
get token map for attributes
constexpr OUStringLiteral gsPropertyAnchorCharStyleName(u"AnchorCharStyleName")
#define XML_TOKEN_MAP_END
Definition: xmltkmap.hxx:33
css::uno::Any const & rValue
Definition: ImageStyle.hxx:38
XmlStyleFamily
Definition: families.hxx:47
constexpr OUStringLiteral gsPropertyParagraphStyleName(u"ParaStyleName")
sal_Int16 nNumType
SvXMLEnumMapEntry< sal_Int16 > const aFootnoteNumberingMap[]
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
XMLFootnoteConfigurationImportContext(SvXMLImport &rImport, sal_Int32 nElement, const css::uno::Reference< css::xml::sax::XFastAttributeList > &xAttrList)
virtual void Finish(bool bOverwrite) override
set configuration at document; calls ProcessSettings
constexpr OUStringLiteral gsPropertyPositionEndOfDoc(u"PositionEndOfDoc")
virtual css::uno::Reference< css::xml::sax::XFastContextHandler > SAL_CALL createFastChildContext(sal_Int32 nElement, const css::uno::Reference< css::xml::sax::XFastAttributeList > &AttrList) override
for footnotes, also parse begin and end notices
constexpr sal_uInt16 XML_NAMESPACE_TEXT
void SetFamily(XmlStyleFamily nSet)
Definition: xmlstyle.hxx:83
constexpr OUStringLiteral gsPropertyEndNotice(u"EndNotice")
constexpr OUStringLiteral gsPropertyPrefix(u"Prefix")
constexpr OUStringLiteral gsPropertyBeginNotice(u"BeginNotice")
import footnote and endnote configuration elements
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
virtual void SAL_CALL endFastElement(sal_Int32 Element) override
Definition: xmlictxt.cxx:114
OUString GetStyleDisplayName(XmlStyleFamily nFamily, const OUString &rName) const
Definition: xmlimp.cxx:1494
constexpr OUStringLiteral gsPropertyStartAt(u"StartAt")
Handling of tokens in XML:
#define XML_ELEMENT(prefix, name)
Definition: xmlimp.hxx:94
const SvXMLUnitConverter & GetMM100UnitConverter() const
Definition: xmlimp.hxx:404
void SetBeginNotice(const OUString &sText)
for helper class: set begin notice
const SvXMLTokenMapEntry aTextFieldAttrTokenMap[]
constexpr OUStringLiteral gsPropertySuffix(u"Suffix")
void SetEndNotice(const OUString &sText)
for helper class: set end notice
SVXCORE_DLLPUBLIC MSO_SPT Get(const OUString &)
constexpr OUStringLiteral gsPropertyPageStyleName(u"PageStyleName")
virtual void SAL_CALL characters(const OUString &aChars) override
Definition: xmlictxt.cxx:142
TEXT
constexpr sal_uInt16 XML_NAMESPACE_STYLE
static bool convertNumber(sal_Int32 &rValue, std::u16string_view aString, sal_Int32 nMin=SAL_MIN_INT32, sal_Int32 nMax=SAL_MAX_INT32)
typedef void(CALLTYPE *GetFuncDataPtr)(sal_uInt16 &nNo