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