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