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 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 133 XMLIndexTemplateContext::~XMLIndexTemplateContext() 134 { 135 } 136 137 138 void XMLIndexTemplateContext::addTemplateEntry( 139 const PropertyValues& aValues) 140 { 141 aValueVector.push_back(aValues); 142 } 143 144 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 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 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