xref: /trunk/main/xmloff/source/text/XMLIndexTemplateContext.cxx (revision cdf0e10c4e3984b49a9502b011690b615761d4a3)
1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_xmloff.hxx"
30 
31 
32 #include "XMLIndexTemplateContext.hxx"
33 #include "XMLIndexSimpleEntryContext.hxx"
34 #include "XMLIndexSpanEntryContext.hxx"
35 #include "XMLIndexTabStopEntryContext.hxx"
36 #include "XMLIndexBibliographyEntryContext.hxx"
37 #include "XMLIndexChapterInfoEntryContext.hxx"
38 #include <xmloff/xmlictxt.hxx>
39 #include <xmloff/xmlimp.hxx>
40 #include <xmloff/txtimp.hxx>
41 #include <xmloff/nmspmap.hxx>
42 #include "xmloff/xmlnmspe.hxx"
43 #include <xmloff/xmltoken.hxx>
44 #include <xmloff/xmluconv.hxx>
45 #include <tools/debug.hxx>
46 #include <rtl/ustring.hxx>
47 #include <rtl/ustrbuf.hxx>
48 #include <com/sun/star/container/XIndexReplace.hpp>
49 
50 
51 using namespace ::std;
52 //using namespace ::com::sun::star::text;
53 using namespace ::xmloff::token;
54 
55 using ::rtl::OUString;
56 using ::rtl::OUStringBuffer;
57 using ::com::sun::star::beans::XPropertySet;
58 using ::com::sun::star::beans::PropertyValue;
59 using ::com::sun::star::beans::PropertyValues;
60 using ::com::sun::star::uno::Reference;
61 using ::com::sun::star::uno::Sequence;
62 using ::com::sun::star::uno::Any;
63 using ::com::sun::star::xml::sax::XAttributeList;
64 using ::com::sun::star::container::XIndexReplace;
65 
66 const sal_Char sAPI_TokenEntryNumber[] =    "TokenEntryNumber";
67 const sal_Char sAPI_TokenEntryText[] =      "TokenEntryText";
68 const sal_Char sAPI_TokenTabStop[] =        "TokenTabStop";
69 const sal_Char sAPI_TokenText[] =           "TokenText";
70 const sal_Char sAPI_TokenPageNumber[] =     "TokenPageNumber";
71 const sal_Char sAPI_TokenChapterInfo[] =    "TokenChapterInfo";
72 const sal_Char sAPI_TokenHyperlinkStart[] = "TokenHyperlinkStart";
73 const sal_Char sAPI_TokenHyperlinkEnd[] =   "TokenHyperlinkEnd";
74 const sal_Char sAPI_TokenBibliographyDataField[] =
75                                             "TokenBibliographyDataField";
76 
77 
78 TYPEINIT1( XMLIndexTemplateContext, SvXMLImportContext);
79 
80 XMLIndexTemplateContext::XMLIndexTemplateContext(
81     SvXMLImport& rImport,
82     Reference<XPropertySet> & rPropSet,
83     sal_uInt16 nPrfx,
84     const OUString& rLocalName,
85     const SvXMLEnumMapEntry* pLevelNameMap,
86     enum XMLTokenEnum eLevelAttrName,
87     const sal_Char** pLevelStylePropMap,
88     const sal_Bool* pAllowedTokenTypes,
89     sal_Bool bT )
90 :   SvXMLImportContext(rImport, nPrfx, rLocalName)
91 ,   pOutlineLevelNameMap(pLevelNameMap)
92 ,   eOutlineLevelAttrName(eLevelAttrName)
93 ,   pOutlineLevelStylePropMap(pLevelStylePropMap)
94 ,   pAllowedTokenTypesMap(pAllowedTokenTypes)
95 ,   nOutlineLevel(1)    // all indices have level 1 (0 is for header)
96 ,   bStyleNameOK(sal_False)
97 ,   bOutlineLevelOK(sal_False)
98 ,   bTOC( bT )
99 ,   rPropertySet(rPropSet)
100 ,   sTokenEntryNumber(RTL_CONSTASCII_USTRINGPARAM(sAPI_TokenEntryNumber))
101 ,   sTokenEntryText(RTL_CONSTASCII_USTRINGPARAM(sAPI_TokenEntryText))
102 ,   sTokenTabStop(RTL_CONSTASCII_USTRINGPARAM(sAPI_TokenTabStop))
103 ,   sTokenText(RTL_CONSTASCII_USTRINGPARAM(sAPI_TokenText))
104 ,   sTokenPageNumber(RTL_CONSTASCII_USTRINGPARAM(sAPI_TokenPageNumber))
105 ,   sTokenChapterInfo(RTL_CONSTASCII_USTRINGPARAM(sAPI_TokenChapterInfo))
106 ,   sTokenHyperlinkStart(RTL_CONSTASCII_USTRINGPARAM(sAPI_TokenHyperlinkStart))
107 ,   sTokenHyperlinkEnd(RTL_CONSTASCII_USTRINGPARAM(sAPI_TokenHyperlinkEnd))
108 ,   sTokenBibliographyDataField(RTL_CONSTASCII_USTRINGPARAM(sAPI_TokenBibliographyDataField))
109 
110 ,   sCharacterStyleName(RTL_CONSTASCII_USTRINGPARAM("CharacterStyleName"))
111 ,   sTokenType(RTL_CONSTASCII_USTRINGPARAM("TokenType"))
112 ,   sText(RTL_CONSTASCII_USTRINGPARAM("Text"))
113 ,   sTabStopRightAligned(RTL_CONSTASCII_USTRINGPARAM("TabStopRightAligned"))
114 ,   sTabStopPosition(RTL_CONSTASCII_USTRINGPARAM("TabStopPosition"))
115 ,   sTabStopFillCharacter(RTL_CONSTASCII_USTRINGPARAM("TabStopFillCharacter"))
116 ,   sBibliographyDataField(RTL_CONSTASCII_USTRINGPARAM("BibliographyDataField"))
117 ,   sChapterFormat(RTL_CONSTASCII_USTRINGPARAM("ChapterFormat"))
118 ,   sChapterLevel(RTL_CONSTASCII_USTRINGPARAM("ChapterLevel")) //#i53420
119 
120 ,   sLevelFormat(RTL_CONSTASCII_USTRINGPARAM("LevelFormat"))
121 ,   sParaStyleLevel(RTL_CONSTASCII_USTRINGPARAM("ParaStyleLevel"))
122 {
123     DBG_ASSERT( ((XML_TOKEN_INVALID != eLevelAttrName) &&  (NULL != pLevelNameMap))
124                 || ((XML_TOKEN_INVALID == eLevelAttrName) &&  (NULL == pLevelNameMap)),
125                 "need both, attribute name and value map, or neither" );
126     DBG_ASSERT( NULL != pOutlineLevelStylePropMap, "need property name map" );
127     DBG_ASSERT( NULL != pAllowedTokenTypes, "need allowed tokens map" );
128 
129     // no map for outline-level? then use 1
130     if (NULL == pLevelNameMap)
131     {
132         nOutlineLevel = 1;
133         bOutlineLevelOK = sal_True;
134     }
135 }
136 
137 XMLIndexTemplateContext::~XMLIndexTemplateContext()
138 {
139 }
140 
141 
142 void XMLIndexTemplateContext::addTemplateEntry(
143     const PropertyValues& aValues)
144 {
145     aValueVector.push_back(aValues);
146 }
147 
148 
149 void XMLIndexTemplateContext::StartElement(
150         const Reference<XAttributeList> & xAttrList)
151 {
152     // process two attributes: style-name, outline-level
153     sal_Int16 nLength = xAttrList->getLength();
154     for(sal_Int16 nAttr = 0; nAttr < nLength; nAttr++)
155     {
156         OUString sLocalName;
157         sal_uInt16 nPrefix = GetImport().GetNamespaceMap().
158             GetKeyByAttrName( xAttrList->getNameByIndex(nAttr),
159                               &sLocalName );
160         if (XML_NAMESPACE_TEXT == nPrefix)
161         {
162             if ( IsXMLToken( sLocalName, XML_STYLE_NAME ) )
163             {
164                 // style name
165                 sStyleName = xAttrList->getValueByIndex(nAttr);
166                 bStyleNameOK = sal_True;
167             }
168             else if (eOutlineLevelAttrName != XML_TOKEN_INVALID)
169             {
170                 // we have an attr name! Then see if we have the attr, too.
171                 if (IsXMLToken(sLocalName, eOutlineLevelAttrName))
172                 {
173                     // outline level
174                     sal_uInt16 nTmp;
175                     if (SvXMLUnitConverter::convertEnum(
176                         nTmp, xAttrList->getValueByIndex(nAttr),
177                         pOutlineLevelNameMap))
178                     {
179                         nOutlineLevel = nTmp;
180                         bOutlineLevelOK = sal_True;
181                     }
182                     // else: illegal value -> ignore
183                 }
184                 // else: unknown attribute -> ignore
185             }
186             // else: we don't care about outline-level -> ignore
187         }
188         // else: attribute not in text namespace -> ignore
189     }
190 }
191 
192 void XMLIndexTemplateContext::EndElement()
193 {
194     if (bOutlineLevelOK)
195     {
196         const sal_Int32 nCount = aValueVector.size();
197         Sequence<PropertyValues> aValueSequence(nCount);
198         for(sal_Int32 i = 0; i<nCount; i++)
199         {
200             aValueSequence[i] = aValueVector[i];
201         }
202 
203         // get LevelFormat IndexReplace ...
204         Any aAny = rPropertySet->getPropertyValue(sLevelFormat);
205         Reference<XIndexReplace> xIndexReplace;
206         aAny >>= xIndexReplace;
207 
208         // ... and insert
209         aAny <<= aValueSequence;
210         xIndexReplace->replaceByIndex(nOutlineLevel, aAny);
211 
212         if (bStyleNameOK)
213         {
214             const sal_Char* pStyleProperty =
215                 pOutlineLevelStylePropMap[nOutlineLevel];
216 
217             DBG_ASSERT(NULL != pStyleProperty, "need property name");
218             if (NULL != pStyleProperty)
219             {
220                 OUString sDisplayStyleName =
221                         GetImport().GetStyleDisplayName(
222                         XML_STYLE_FAMILY_TEXT_PARAGRAPH,
223                         sStyleName );
224                 // #i50288#: Check if style exists
225                 const Reference < ::com::sun::star::container::XNameContainer > & rStyles =
226                     GetImport().GetTextImport()->GetParaStyles();
227                 if( rStyles.is() &&
228                     rStyles->hasByName( sDisplayStyleName ) )
229                 {
230                     aAny <<= sDisplayStyleName;
231                     rPropertySet->setPropertyValue(
232                         OUString::createFromAscii(pStyleProperty), aAny);
233                 }
234             }
235         }
236     }
237 }
238 
239 
240 
241 /// template token types; used for aTokenTypeMap parameter
242 enum TemplateTokenType
243 {
244     XML_TOK_INDEX_TYPE_ENTRY_TEXT = 0,
245     XML_TOK_INDEX_TYPE_TAB_STOP,
246     XML_TOK_INDEX_TYPE_TEXT,
247     XML_TOK_INDEX_TYPE_PAGE_NUMBER,
248     XML_TOK_INDEX_TYPE_CHAPTER,
249     XML_TOK_INDEX_TYPE_LINK_START,
250     XML_TOK_INDEX_TYPE_LINK_END,
251     XML_TOK_INDEX_TYPE_BIBLIOGRAPHY
252 };
253 
254 
255 SvXMLEnumMapEntry aTemplateTokenTypeMap[] =
256 {
257     { XML_INDEX_ENTRY_TEXT,         XML_TOK_INDEX_TYPE_ENTRY_TEXT },
258     { XML_INDEX_ENTRY_TAB_STOP,     XML_TOK_INDEX_TYPE_TAB_STOP },
259     { XML_INDEX_ENTRY_SPAN,         XML_TOK_INDEX_TYPE_TEXT },
260     { XML_INDEX_ENTRY_PAGE_NUMBER,  XML_TOK_INDEX_TYPE_PAGE_NUMBER },
261     { XML_INDEX_ENTRY_CHAPTER,      XML_TOK_INDEX_TYPE_CHAPTER },
262     { XML_INDEX_ENTRY_LINK_START,   XML_TOK_INDEX_TYPE_LINK_START },
263     { XML_INDEX_ENTRY_LINK_END,     XML_TOK_INDEX_TYPE_LINK_END },
264     { XML_INDEX_ENTRY_BIBLIOGRAPHY, XML_TOK_INDEX_TYPE_BIBLIOGRAPHY },
265     { XML_TOKEN_INVALID, 0 }
266 };
267 
268 SvXMLImportContext *XMLIndexTemplateContext::CreateChildContext(
269     sal_uInt16 nPrefix,
270     const OUString& rLocalName,
271     const Reference<XAttributeList> & xAttrList )
272 {
273     SvXMLImportContext* pContext = NULL;
274 
275     if (XML_NAMESPACE_TEXT == nPrefix)
276     {
277         sal_uInt16 nToken;
278         if (SvXMLUnitConverter::convertEnum(nToken, rLocalName,
279                                             aTemplateTokenTypeMap))
280         {
281             // can this index accept this kind of token?
282             if (pAllowedTokenTypesMap[nToken])
283             {
284                 switch ((TemplateTokenType)nToken)
285                 {
286                     case XML_TOK_INDEX_TYPE_ENTRY_TEXT:
287                         pContext = new XMLIndexSimpleEntryContext(
288                             GetImport(), sTokenEntryText, *this,
289                             nPrefix, rLocalName);
290                         break;
291 
292                     case XML_TOK_INDEX_TYPE_PAGE_NUMBER:
293                         pContext = new XMLIndexSimpleEntryContext(
294                             GetImport(), sTokenPageNumber, *this,
295                             nPrefix, rLocalName);
296                         break;
297 
298                     case XML_TOK_INDEX_TYPE_LINK_START:
299                         pContext = new XMLIndexSimpleEntryContext(
300                             GetImport(), sTokenHyperlinkStart, *this,
301                             nPrefix, rLocalName);
302                         break;
303 
304                     case XML_TOK_INDEX_TYPE_LINK_END:
305                         pContext = new XMLIndexSimpleEntryContext(
306                             GetImport(), sTokenHyperlinkEnd, *this,
307                             nPrefix, rLocalName);
308                         break;
309 
310                     case XML_TOK_INDEX_TYPE_TEXT:
311                         pContext = new XMLIndexSpanEntryContext(
312                             GetImport(), *this, nPrefix, rLocalName);
313                         break;
314 
315                     case XML_TOK_INDEX_TYPE_TAB_STOP:
316                         pContext = new XMLIndexTabStopEntryContext(
317                             GetImport(), *this, nPrefix, rLocalName);
318                         break;
319 
320                     case XML_TOK_INDEX_TYPE_BIBLIOGRAPHY:
321                         pContext = new XMLIndexBibliographyEntryContext(
322                             GetImport(), *this, nPrefix, rLocalName);
323                         break;
324 
325                     case XML_TOK_INDEX_TYPE_CHAPTER:
326                         pContext = new XMLIndexChapterInfoEntryContext(
327                             GetImport(), *this, nPrefix, rLocalName, bTOC );
328                         break;
329 
330                     default:
331                         // ignore!
332                         break;
333                 }
334             }
335         }
336     }
337 
338     // ignore unknown
339     if (NULL == pContext)
340     {
341         return SvXMLImportContext::CreateChildContext(nPrefix, rLocalName,
342                                                       xAttrList);
343     }
344 
345     return pContext;
346 }
347 
348 
349 
350 //
351 // maps for the XMLIndexTemplateContext constructor
352 //
353 
354 
355 // table of content and user defined index:
356 
357 const SvXMLEnumMapEntry aLevelNameTOCMap[] =
358 {
359     { XML_1, 1 },
360     { XML_2, 2 },
361     { XML_3, 3 },
362     { XML_4, 4 },
363     { XML_5, 5 },
364     { XML_6, 6 },
365     { XML_7, 7 },
366     { XML_8, 8 },
367     { XML_9, 9 },
368     { XML_10, 10 },
369     { XML_TOKEN_INVALID, 0 }
370 };
371 
372 const sal_Char* aLevelStylePropNameTOCMap[] =
373     { NULL, "ParaStyleLevel1", "ParaStyleLevel2", "ParaStyleLevel3",
374           "ParaStyleLevel4", "ParaStyleLevel5", "ParaStyleLevel6",
375           "ParaStyleLevel7", "ParaStyleLevel8", "ParaStyleLevel9",
376           "ParaStyleLevel10", NULL };
377 
378 const sal_Bool aAllowedTokenTypesTOC[] =
379 {
380     sal_True,       // XML_TOK_INDEX_TYPE_ENTRY_TEXT =
381     sal_True,       // XML_TOK_INDEX_TYPE_TAB_STOP,
382     sal_True,       // XML_TOK_INDEX_TYPE_TEXT,
383     sal_True,       // XML_TOK_INDEX_TYPE_PAGE_NUMBER,
384     sal_True,       // XML_TOK_INDEX_TYPE_CHAPTER,
385     sal_True,       // XML_TOK_INDEX_TYPE_LINK_START,
386     sal_True,       // XML_TOK_INDEX_TYPE_LINK_END,
387     sal_False       // XML_TOK_INDEX_TYPE_BIBLIOGRAPHY
388 };
389 
390 const sal_Bool aAllowedTokenTypesUser[] =
391 {
392     sal_True,       // XML_TOK_INDEX_TYPE_ENTRY_TEXT =
393     sal_True,       // XML_TOK_INDEX_TYPE_TAB_STOP,
394     sal_True,       // XML_TOK_INDEX_TYPE_TEXT,
395     sal_True,       // XML_TOK_INDEX_TYPE_PAGE_NUMBER,
396     sal_True,       // XML_TOK_INDEX_TYPE_CHAPTER,
397     sal_False,      // XML_TOK_INDEX_TYPE_LINK_START,
398     sal_False,      // XML_TOK_INDEX_TYPE_LINK_END,
399     sal_False       // XML_TOK_INDEX_TYPE_BIBLIOGRAPHY
400 };
401 
402 
403 // alphabetical index
404 
405 const SvXMLEnumMapEntry aLevelNameAlphaMap[] =
406 {
407     { XML_SEPARATOR, 1 },
408     { XML_1, 2 },
409     { XML_2, 3 },
410     { XML_3, 4 },
411     { XML_TOKEN_INVALID, 0 }
412 };
413 
414 const sal_Char* aLevelStylePropNameAlphaMap[] =
415     { NULL, "ParaStyleSeparator", "ParaStyleLevel1", "ParaStyleLevel2",
416           "ParaStyleLevel3", NULL };
417 
418 const sal_Bool aAllowedTokenTypesAlpha[] =
419 {
420     sal_True,       // XML_TOK_INDEX_TYPE_ENTRY_TEXT =
421     sal_True,       // XML_TOK_INDEX_TYPE_TAB_STOP,
422     sal_True,       // XML_TOK_INDEX_TYPE_TEXT,
423     sal_True,       // XML_TOK_INDEX_TYPE_PAGE_NUMBER,
424     sal_True,       // XML_TOK_INDEX_TYPE_CHAPTER,
425     sal_False,      // XML_TOK_INDEX_TYPE_LINK_START,
426     sal_False,      // XML_TOK_INDEX_TYPE_LINK_END,
427     sal_False       // XML_TOK_INDEX_TYPE_BIBLIOGRAPHY
428 };
429 
430 
431 // bibliography index:
432 
433 const SvXMLEnumMapEntry aLevelNameBibliographyMap[] =
434 {
435     { XML_ARTICLE, 1 },
436     { XML_BOOK, 2 },
437     { XML_BOOKLET, 3 },
438     { XML_CONFERENCE, 4 },
439     { XML_CUSTOM1, 5 },
440     { XML_CUSTOM2, 6 },
441     { XML_CUSTOM3, 7 },
442     { XML_CUSTOM4, 8 },
443     { XML_CUSTOM5, 9 },
444     { XML_EMAIL, 10 },
445     { XML_INBOOK, 11 },
446     { XML_INCOLLECTION, 12 },
447     { XML_INPROCEEDINGS, 13 },
448     { XML_JOURNAL, 14 },
449     { XML_MANUAL, 15 },
450     { XML_MASTERSTHESIS, 16 },
451     { XML_MISC, 17 },
452     { XML_PHDTHESIS, 18 },
453     { XML_PROCEEDINGS, 19 },
454     { XML_TECHREPORT, 20 },
455     { XML_UNPUBLISHED, 21 },
456     { XML_WWW, 22 },
457     { XML_TOKEN_INVALID, 0 }
458 };
459 
460 // TODO: replace with real property names, when available
461 const sal_Char* aLevelStylePropNameBibliographyMap[] =
462 {
463     NULL, "ParaStyleLevel1", "ParaStyleLevel1", "ParaStyleLevel1",
464     "ParaStyleLevel1", "ParaStyleLevel1", "ParaStyleLevel1",
465     "ParaStyleLevel1", "ParaStyleLevel1", "ParaStyleLevel1",
466     "ParaStyleLevel1", "ParaStyleLevel1", "ParaStyleLevel1",
467     "ParaStyleLevel1", "ParaStyleLevel1", "ParaStyleLevel1",
468     "ParaStyleLevel1", "ParaStyleLevel1", "ParaStyleLevel1",
469     "ParaStyleLevel1", "ParaStyleLevel1", "ParaStyleLevel1",
470     "ParaStyleLevel1", NULL };
471 
472 const sal_Bool aAllowedTokenTypesBibliography[] =
473 {
474     sal_True,       // XML_TOK_INDEX_TYPE_ENTRY_TEXT =
475     sal_True,       // XML_TOK_INDEX_TYPE_TAB_STOP,
476     sal_True,       // XML_TOK_INDEX_TYPE_TEXT,
477     sal_True,       // XML_TOK_INDEX_TYPE_PAGE_NUMBER,
478     sal_False,      // XML_TOK_INDEX_TYPE_CHAPTER,
479     sal_False,      // XML_TOK_INDEX_TYPE_LINK_START,
480     sal_False,      // XML_TOK_INDEX_TYPE_LINK_END,
481     sal_True        // XML_TOK_INDEX_TYPE_BIBLIOGRAPHY
482 };
483 
484 
485 // table, illustration and object index
486 
487 // no name map
488 const SvXMLEnumMapEntry* aLevelNameTableMap = NULL;
489 
490 const sal_Char* aLevelStylePropNameTableMap[] =
491     { NULL, "ParaStyleLevel1", NULL };
492 
493 const sal_Bool aAllowedTokenTypesTable[] =
494 {
495     sal_True,       // XML_TOK_INDEX_TYPE_ENTRY_TEXT =
496     sal_True,       // XML_TOK_INDEX_TYPE_TAB_STOP,
497     sal_True,       // XML_TOK_INDEX_TYPE_TEXT,
498     sal_True,       // XML_TOK_INDEX_TYPE_PAGE_NUMBER,
499     sal_True,       // XML_TOK_INDEX_TYPE_CHAPTER,
500     sal_False,      // XML_TOK_INDEX_TYPE_LINK_START,
501     sal_False,      // XML_TOK_INDEX_TYPE_LINK_END,
502     sal_False       // XML_TOK_INDEX_TYPE_BIBLIOGRAPHY
503 };
504 
505