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