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