Line data Source code
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 :
21 : #include "XMLFootnoteConfigurationImportContext.hxx"
22 :
23 : #include <rtl/ustring.hxx>
24 : #include <rtl/ustrbuf.hxx>
25 :
26 : #include <sax/tools/converter.hxx>
27 :
28 : #include <xmloff/nmspmap.hxx>
29 : #include <xmloff/xmlnmspe.hxx>
30 : #include <xmloff/xmltoken.hxx>
31 :
32 : #include <xmloff/families.hxx>
33 : #include <xmloff/xmluconv.hxx>
34 : #include <xmloff/xmlimp.hxx>
35 : #include <xmloff/xmlnumi.hxx>
36 : #include <com/sun/star/xml/sax/XAttributeList.hpp>
37 : #include <com/sun/star/beans/XPropertySet.hpp>
38 : #include <com/sun/star/text/XFootnote.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 :
46 : using namespace ::com::sun::star::text;
47 : using namespace ::com::sun::star::beans;
48 : using namespace ::com::sun::star::uno;
49 : using namespace ::com::sun::star::style;
50 : using namespace ::com::sun::star::xml::sax;
51 : using namespace ::xmloff::token;
52 :
53 :
54 : // XMLFootnoteConfigHelper
55 :
56 :
57 : /// local helper class for import of quo-vadis and ergo-sum elements
58 0 : class XMLFootnoteConfigHelper : public SvXMLImportContext
59 : {
60 : OUStringBuffer sBuffer;
61 : XMLFootnoteConfigurationImportContext& rConfig;
62 : bool bIsBegin;
63 :
64 : public:
65 : TYPEINFO_OVERRIDE();
66 :
67 : XMLFootnoteConfigHelper(
68 : SvXMLImport& rImport,
69 : sal_uInt16 nPrfx,
70 : const OUString& rLName,
71 : XMLFootnoteConfigurationImportContext& rConfigImport,
72 : bool bBegin);
73 :
74 : virtual void EndElement() SAL_OVERRIDE;
75 :
76 : virtual void Characters( const OUString& rChars ) SAL_OVERRIDE;
77 : };
78 :
79 0 : TYPEINIT1( XMLFootnoteConfigHelper, SvXMLImportContext );
80 :
81 0 : XMLFootnoteConfigHelper::XMLFootnoteConfigHelper(
82 : SvXMLImport& rImport,
83 : sal_uInt16 nPrfx,
84 : const OUString& rLName,
85 : XMLFootnoteConfigurationImportContext& rConfigImport,
86 : bool bBegin)
87 : : SvXMLImportContext(rImport, nPrfx, rLName)
88 : , sBuffer()
89 : , rConfig(rConfigImport)
90 0 : , bIsBegin(bBegin)
91 : {
92 0 : }
93 :
94 0 : void XMLFootnoteConfigHelper::EndElement()
95 : {
96 0 : if (bIsBegin)
97 : {
98 0 : rConfig.SetBeginNotice(sBuffer.makeStringAndClear());
99 : }
100 : else
101 : {
102 0 : rConfig.SetEndNotice(sBuffer.makeStringAndClear());
103 : }
104 : // rConfig = NULL; // import contexts are ref-counted
105 0 : }
106 :
107 0 : void XMLFootnoteConfigHelper::Characters( const OUString& rChars )
108 : {
109 0 : sBuffer.append(rChars);
110 0 : }
111 :
112 :
113 :
114 : // XMLFootnoteConfigurationImportContext
115 :
116 :
117 :
118 0 : TYPEINIT1( XMLFootnoteConfigurationImportContext, SvXMLStyleContext );
119 :
120 0 : XMLFootnoteConfigurationImportContext::XMLFootnoteConfigurationImportContext(
121 : SvXMLImport& rImport,
122 : sal_uInt16 nPrfx,
123 : const OUString& rLocalName,
124 : const Reference<XAttributeList> & xAttrList)
125 : : SvXMLStyleContext(rImport, nPrfx, rLocalName, xAttrList, XML_STYLE_FAMILY_TEXT_FOOTNOTECONFIG)
126 : , sPropertyAnchorCharStyleName("AnchorCharStyleName")
127 : , sPropertyCharStyleName("CharStyleName")
128 : , sPropertyNumberingType("NumberingType")
129 : , sPropertyPageStyleName("PageStyleName")
130 : , sPropertyParagraphStyleName("ParaStyleName")
131 : , sPropertyPrefix("Prefix")
132 : , sPropertyStartAt("StartAt")
133 : , sPropertySuffix("Suffix")
134 : , sPropertyPositionEndOfDoc("PositionEndOfDoc")
135 : , sPropertyFootnoteCounting("FootnoteCounting")
136 : , sPropertyEndNotice("EndNotice")
137 : , sPropertyBeginNotice("BeginNotice")
138 : , sNumFormat("1")
139 : , sNumSync("false")
140 : , pAttrTokenMap(NULL)
141 : , nOffset(0)
142 : , nNumbering(FootnoteNumbering::PER_PAGE)
143 : , bPosition(sal_False)
144 0 : , bIsEndnote(sal_False)
145 : {
146 0 : sal_Int16 nLength = xAttrList->getLength();
147 0 : for(sal_Int16 nAttr = 0; nAttr < nLength; nAttr++)
148 : {
149 0 : OUString sLocalName;
150 0 : sal_uInt16 nPrefix = GetImport().GetNamespaceMap().
151 0 : GetKeyByAttrName( xAttrList->getNameByIndex(nAttr),
152 0 : &sLocalName );
153 0 : if( XML_NAMESPACE_TEXT == nPrefix && IsXMLToken( sLocalName,
154 0 : XML_NOTE_CLASS ) )
155 : {
156 0 : const OUString& rValue = xAttrList->getValueByIndex( nAttr );
157 0 : if( IsXMLToken( rValue, XML_ENDNOTE ) )
158 : {
159 0 : bIsEndnote = sal_True;
160 0 : SetFamily( XML_STYLE_FAMILY_TEXT_FOOTNOTECONFIG );
161 : }
162 0 : break;
163 : }
164 0 : }
165 :
166 0 : }
167 0 : XMLFootnoteConfigurationImportContext::~XMLFootnoteConfigurationImportContext()
168 : {
169 0 : delete pAttrTokenMap;
170 0 : }
171 :
172 : enum XMLFtnConfigToken
173 : {
174 : XML_TOK_FTNCONFIG_CITATION_STYLENAME,
175 : XML_TOK_FTNCONFIG_ANCHOR_STYLENAME,
176 : XML_TOK_FTNCONFIG_DEFAULT_STYLENAME,
177 : XML_TOK_FTNCONFIG_PAGE_STYLENAME,
178 : XML_TOK_FTNCONFIG_OFFSET,
179 : XML_TOK_FTNCONFIG_NUM_PREFIX,
180 : XML_TOK_FTNCONFIG_NUM_SUFFIX,
181 : XML_TOK_FTNCONFIG_NUM_FORMAT,
182 : XML_TOK_FTNCONFIG_NUM_SYNC,
183 : XML_TOK_FTNCONFIG_START_AT,
184 : XML_TOK_FTNCONFIG_POSITION
185 : };
186 :
187 : static const SvXMLTokenMapEntry aTextFieldAttrTokenMap[] =
188 : {
189 : { XML_NAMESPACE_TEXT, XML_CITATION_STYLE_NAME, XML_TOK_FTNCONFIG_CITATION_STYLENAME },
190 : { XML_NAMESPACE_TEXT, XML_CITATION_BODY_STYLE_NAME, XML_TOK_FTNCONFIG_ANCHOR_STYLENAME },
191 : { XML_NAMESPACE_TEXT, XML_DEFAULT_STYLE_NAME, XML_TOK_FTNCONFIG_DEFAULT_STYLENAME },
192 : { XML_NAMESPACE_TEXT, XML_MASTER_PAGE_NAME, XML_TOK_FTNCONFIG_PAGE_STYLENAME },
193 : { XML_NAMESPACE_TEXT, XML_START_VALUE, XML_TOK_FTNCONFIG_OFFSET },
194 : { XML_NAMESPACE_STYLE, XML_NUM_PREFIX, XML_TOK_FTNCONFIG_NUM_PREFIX },
195 : { XML_NAMESPACE_STYLE, XML_NUM_SUFFIX, XML_TOK_FTNCONFIG_NUM_SUFFIX },
196 : { XML_NAMESPACE_STYLE, XML_NUM_FORMAT, XML_TOK_FTNCONFIG_NUM_FORMAT },
197 : { XML_NAMESPACE_STYLE, XML_NUM_LETTER_SYNC, XML_TOK_FTNCONFIG_NUM_SYNC },
198 : { XML_NAMESPACE_TEXT, XML_START_NUMBERING_AT, XML_TOK_FTNCONFIG_START_AT},
199 : { XML_NAMESPACE_TEXT, XML_FOOTNOTES_POSITION, XML_TOK_FTNCONFIG_POSITION},
200 :
201 : // for backwards compatibility with SRC630 & earlier
202 : { XML_NAMESPACE_TEXT, XML_NUM_PREFIX, XML_TOK_FTNCONFIG_NUM_PREFIX },
203 : { XML_NAMESPACE_TEXT, XML_NUM_SUFFIX, XML_TOK_FTNCONFIG_NUM_SUFFIX },
204 : { XML_NAMESPACE_TEXT, XML_OFFSET, XML_TOK_FTNCONFIG_OFFSET },
205 : XML_TOKEN_MAP_END
206 : };
207 :
208 : const SvXMLTokenMap&
209 0 : XMLFootnoteConfigurationImportContext::GetFtnConfigAttrTokenMap()
210 : {
211 0 : if (NULL == pAttrTokenMap)
212 : {
213 0 : pAttrTokenMap = new SvXMLTokenMap(aTextFieldAttrTokenMap);
214 : }
215 :
216 0 : return *pAttrTokenMap;
217 : }
218 :
219 : static SvXMLEnumMapEntry const aFootnoteNumberingMap[] =
220 : {
221 : { XML_PAGE, FootnoteNumbering::PER_PAGE },
222 : { XML_CHAPTER, FootnoteNumbering::PER_CHAPTER },
223 : { XML_DOCUMENT, FootnoteNumbering::PER_DOCUMENT },
224 : { XML_TOKEN_INVALID, 0 },
225 : };
226 :
227 0 : void XMLFootnoteConfigurationImportContext::StartElement(
228 : const Reference<XAttributeList> & xAttrList )
229 : {
230 0 : sal_Int16 nLength = xAttrList->getLength();
231 0 : for(sal_Int16 nAttr = 0; nAttr < nLength; nAttr++)
232 : {
233 0 : OUString sLocalName;
234 0 : sal_uInt16 nPrefix = GetImport().GetNamespaceMap().
235 0 : GetKeyByAttrName( xAttrList->getNameByIndex(nAttr),
236 0 : &sLocalName );
237 0 : OUString sValue = xAttrList->getValueByIndex(nAttr);
238 0 : switch (GetFtnConfigAttrTokenMap().Get(nPrefix, sLocalName))
239 : {
240 : case XML_TOK_FTNCONFIG_CITATION_STYLENAME:
241 0 : sCitationStyle = sValue;
242 0 : break;
243 : case XML_TOK_FTNCONFIG_ANCHOR_STYLENAME:
244 0 : sAnchorStyle = sValue;
245 0 : break;
246 : case XML_TOK_FTNCONFIG_DEFAULT_STYLENAME:
247 0 : sDefaultStyle = sValue;
248 0 : break;
249 : case XML_TOK_FTNCONFIG_PAGE_STYLENAME:
250 0 : sPageStyle = sValue;
251 0 : break;
252 : case XML_TOK_FTNCONFIG_OFFSET:
253 : {
254 : sal_Int32 nTmp;
255 0 : if (::sax::Converter::convertNumber(nTmp, sValue))
256 : {
257 0 : nOffset = (sal_uInt16)nTmp;
258 : }
259 0 : break;
260 : }
261 : case XML_TOK_FTNCONFIG_NUM_PREFIX:
262 0 : sPrefix = sValue;
263 0 : break;
264 : case XML_TOK_FTNCONFIG_NUM_SUFFIX:
265 0 : sSuffix = sValue;
266 0 : break;
267 : case XML_TOK_FTNCONFIG_NUM_FORMAT:
268 0 : sNumFormat = sValue;
269 0 : break;
270 : case XML_TOK_FTNCONFIG_NUM_SYNC:
271 0 : sNumSync = sValue;
272 0 : break;
273 : case XML_TOK_FTNCONFIG_START_AT:
274 : {
275 : sal_uInt16 nTmp;
276 0 : if (SvXMLUnitConverter::convertEnum(nTmp, sValue,
277 : aFootnoteNumberingMap))
278 : {
279 0 : nNumbering = nTmp;
280 : }
281 0 : break;
282 : }
283 : case XML_TOK_FTNCONFIG_POSITION:
284 0 : bPosition = IsXMLToken( sValue, XML_DOCUMENT );
285 0 : break;
286 : default:
287 : ; // ignore
288 : }
289 0 : }
290 0 : }
291 :
292 0 : SvXMLImportContext *XMLFootnoteConfigurationImportContext::CreateChildContext(
293 : sal_uInt16 nPrefix,
294 : const OUString& rLocalName,
295 : const Reference<XAttributeList> & xAttrList )
296 : {
297 0 : SvXMLImportContext* pContext = NULL;
298 :
299 0 : if (!bIsEndnote)
300 : {
301 0 : if (XML_NAMESPACE_TEXT == nPrefix)
302 : {
303 0 : if ( IsXMLToken( rLocalName,
304 : XML_FOOTNOTE_CONTINUATION_NOTICE_FORWARD ) )
305 : {
306 0 : pContext = new XMLFootnoteConfigHelper(GetImport(),
307 : nPrefix, rLocalName,
308 0 : *this, false);
309 : }
310 0 : else if ( IsXMLToken( rLocalName,
311 : XML_FOOTNOTE_CONTINUATION_NOTICE_BACKWARD ) )
312 : {
313 0 : pContext = new XMLFootnoteConfigHelper(GetImport(),
314 : nPrefix, rLocalName,
315 0 : *this, true);
316 : }
317 : // else: default context
318 : }
319 : // else: unknown namespace -> default context
320 : }
321 : // else: endnote -> default context
322 :
323 0 : if (pContext == NULL)
324 : {
325 : // default: delegate to super class
326 : pContext = SvXMLStyleContext::CreateChildContext(nPrefix,
327 : rLocalName,
328 0 : xAttrList);
329 : }
330 :
331 0 : return pContext;
332 : }
333 :
334 : // Rename method <CreateAndInsertLate(..)> to <Finish(..)> (#i40597#)
335 0 : void XMLFootnoteConfigurationImportContext::Finish( bool bOverwrite )
336 : {
337 :
338 0 : if (bOverwrite)
339 : {
340 0 : if (bIsEndnote)
341 : {
342 : Reference<XEndnotesSupplier> xSupplier(
343 0 : GetImport().GetModel(), UNO_QUERY);
344 0 : if (xSupplier.is())
345 : {
346 0 : ProcessSettings(xSupplier->getEndnoteSettings());
347 0 : }
348 : }
349 : else
350 : {
351 : Reference<XFootnotesSupplier> xSupplier(
352 0 : GetImport().GetModel(), UNO_QUERY);
353 0 : if (xSupplier.is())
354 : {
355 0 : ProcessSettings(xSupplier->getFootnoteSettings());
356 0 : }
357 : }
358 : }
359 : // else: ignore (there's only one configuration, so we can only overwrite)
360 0 : }
361 :
362 0 : void XMLFootnoteConfigurationImportContext::ProcessSettings(
363 : const Reference<XPropertySet> & rConfig)
364 : {
365 0 : Any aAny;
366 :
367 0 : if (!sCitationStyle.isEmpty())
368 : {
369 0 : aAny <<= GetImport().GetStyleDisplayName(
370 0 : XML_STYLE_FAMILY_TEXT_TEXT, sCitationStyle );
371 0 : rConfig->setPropertyValue(sPropertyCharStyleName, aAny);
372 : }
373 :
374 0 : if (!sAnchorStyle.isEmpty())
375 : {
376 0 : aAny <<= GetImport().GetStyleDisplayName(
377 0 : XML_STYLE_FAMILY_TEXT_TEXT, sAnchorStyle );
378 0 : rConfig->setPropertyValue(sPropertyAnchorCharStyleName, aAny);
379 : }
380 :
381 0 : if (!sPageStyle.isEmpty())
382 : {
383 0 : aAny <<= GetImport().GetStyleDisplayName(
384 0 : XML_STYLE_FAMILY_MASTER_PAGE, sPageStyle );
385 0 : rConfig->setPropertyValue(sPropertyPageStyleName, aAny);
386 : }
387 :
388 0 : if (!sDefaultStyle.isEmpty())
389 : {
390 0 : aAny <<= GetImport().GetStyleDisplayName(
391 0 : XML_STYLE_FAMILY_TEXT_PARAGRAPH, sDefaultStyle );
392 0 : rConfig->setPropertyValue(sPropertyParagraphStyleName, aAny);
393 : }
394 :
395 0 : aAny <<= sPrefix;
396 0 : rConfig->setPropertyValue(sPropertyPrefix, aAny);
397 :
398 0 : aAny <<= sSuffix;
399 0 : rConfig->setPropertyValue(sPropertySuffix, aAny);
400 :
401 0 : sal_Int16 nNumType = NumberingType::ARABIC;
402 0 : GetImport().GetMM100UnitConverter().convertNumFormat( nNumType, sNumFormat,
403 0 : sNumSync );
404 : // #i61399: Corrupt file? It contains "Bullet" as numbering style for footnotes.
405 : // Okay, even it seems to be corrupt, we will oversee this and set the style to ARABIC
406 0 : if( NumberingType::CHAR_SPECIAL == nNumType )
407 0 : nNumType = NumberingType::ARABIC;
408 :
409 0 : aAny <<= nNumType;
410 0 : rConfig->setPropertyValue(sPropertyNumberingType, aAny);
411 :
412 0 : aAny <<= nOffset;
413 0 : rConfig->setPropertyValue(sPropertyStartAt, aAny);
414 :
415 0 : if (!bIsEndnote)
416 : {
417 0 : aAny.setValue(&bPosition, ::getBooleanCppuType());
418 0 : rConfig->setPropertyValue(sPropertyPositionEndOfDoc, aAny);
419 :
420 0 : aAny <<= nNumbering;
421 0 : rConfig->setPropertyValue(sPropertyFootnoteCounting, aAny);
422 :
423 0 : aAny <<= sEndNotice;
424 0 : rConfig->setPropertyValue(sPropertyEndNotice, aAny);
425 :
426 0 : aAny <<= sBeginNotice;
427 0 : rConfig->setPropertyValue(sPropertyBeginNotice, aAny);
428 0 : }
429 0 : }
430 :
431 0 : void XMLFootnoteConfigurationImportContext::SetBeginNotice(
432 : const OUString& sText)
433 : {
434 0 : sBeginNotice = sText;
435 0 : }
436 :
437 0 : void XMLFootnoteConfigurationImportContext::SetEndNotice(
438 : const OUString& sText)
439 : {
440 0 : sEndNotice = sText;
441 0 : }
442 :
443 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|