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 #include "XMLFootnoteConfigurationImportContext.hxx" 31 32 #ifndef _RTL_USTRING 33 #include <rtl/ustring.hxx> 34 #endif 35 #include <rtl/ustrbuf.hxx> 36 #include <tools/debug.hxx> 37 #include <xmloff/nmspmap.hxx> 38 #include "xmloff/xmlnmspe.hxx" 39 #include <xmloff/xmltoken.hxx> 40 41 #ifndef _XMLOFF_FAMILIES_HXX 42 #include <xmloff/families.hxx> 43 #endif 44 #include <xmloff/xmluconv.hxx> 45 #include <xmloff/xmlimp.hxx> 46 #include <xmloff/xmlnumi.hxx> 47 #include <com/sun/star/xml/sax/XAttributeList.hpp> 48 #include <com/sun/star/beans/XPropertySet.hpp> 49 #include <com/sun/star/text/XFootnote.hpp> 50 #include <com/sun/star/text/XFootnotesSupplier.hpp> 51 #include <com/sun/star/text/XEndnotesSupplier.hpp> 52 #include <com/sun/star/text/FootnoteNumbering.hpp> 53 #include <com/sun/star/style/NumberingType.hpp> 54 55 56 using ::rtl::OUString; 57 using ::rtl::OUStringBuffer; 58 59 using namespace ::com::sun::star::text; 60 using namespace ::com::sun::star::beans; 61 using namespace ::com::sun::star::uno; 62 using namespace ::com::sun::star::style; 63 using namespace ::com::sun::star::xml::sax; 64 using namespace ::xmloff::token; 65 66 // 67 // XMLFootnoteConfigHelper 68 // 69 70 /// local helper class for import of quo-vadis and ergo-sum elements 71 class XMLFootnoteConfigHelper : public SvXMLImportContext 72 { 73 OUStringBuffer sBuffer; 74 XMLFootnoteConfigurationImportContext& rConfig; 75 sal_Bool bIsBegin; 76 77 public: 78 TYPEINFO(); 79 80 XMLFootnoteConfigHelper( 81 SvXMLImport& rImport, 82 sal_uInt16 nPrfx, 83 const OUString& rLName, 84 XMLFootnoteConfigurationImportContext& rConfigImport, 85 sal_Bool bBegin); 86 87 virtual void EndElement(); 88 89 virtual void Characters( const OUString& rChars ); 90 }; 91 92 TYPEINIT1( XMLFootnoteConfigHelper, SvXMLImportContext ); 93 94 XMLFootnoteConfigHelper::XMLFootnoteConfigHelper( 95 SvXMLImport& rImport, 96 sal_uInt16 nPrfx, 97 const OUString& rLName, 98 XMLFootnoteConfigurationImportContext& rConfigImport, 99 sal_Bool bBegin) 100 : SvXMLImportContext(rImport, nPrfx, rLName) 101 , sBuffer() 102 , rConfig(rConfigImport) 103 , bIsBegin(bBegin) 104 { 105 } 106 107 void XMLFootnoteConfigHelper::EndElement() 108 { 109 if (bIsBegin) 110 { 111 rConfig.SetBeginNotice(sBuffer.makeStringAndClear()); 112 } 113 else 114 { 115 rConfig.SetEndNotice(sBuffer.makeStringAndClear()); 116 } 117 // rConfig = NULL; // import contexts are ref-counted 118 } 119 120 void XMLFootnoteConfigHelper::Characters( const OUString& rChars ) 121 { 122 sBuffer.append(rChars); 123 } 124 125 126 // 127 // XMLFootnoteConfigurationImportContext 128 // 129 130 131 TYPEINIT1( XMLFootnoteConfigurationImportContext, SvXMLStyleContext ); 132 133 XMLFootnoteConfigurationImportContext::XMLFootnoteConfigurationImportContext( 134 SvXMLImport& rImport, 135 sal_uInt16 nPrfx, 136 const OUString& rLocalName, 137 const Reference<XAttributeList> & xAttrList) 138 : SvXMLStyleContext(rImport, nPrfx, rLocalName, xAttrList, XML_STYLE_FAMILY_TEXT_FOOTNOTECONFIG) 139 , sPropertyAnchorCharStyleName(RTL_CONSTASCII_USTRINGPARAM("AnchorCharStyleName")) 140 , sPropertyCharStyleName(RTL_CONSTASCII_USTRINGPARAM("CharStyleName")) 141 , sPropertyNumberingType(RTL_CONSTASCII_USTRINGPARAM("NumberingType")) 142 , sPropertyPageStyleName(RTL_CONSTASCII_USTRINGPARAM("PageStyleName")) 143 , sPropertyParagraphStyleName(RTL_CONSTASCII_USTRINGPARAM("ParaStyleName")) 144 , sPropertyPrefix(RTL_CONSTASCII_USTRINGPARAM("Prefix")) 145 , sPropertyStartAt(RTL_CONSTASCII_USTRINGPARAM("StartAt")) 146 , sPropertySuffix(RTL_CONSTASCII_USTRINGPARAM("Suffix")) 147 , sPropertyPositionEndOfDoc(RTL_CONSTASCII_USTRINGPARAM("PositionEndOfDoc")) 148 , sPropertyFootnoteCounting(RTL_CONSTASCII_USTRINGPARAM("FootnoteCounting")) 149 , sPropertyEndNotice(RTL_CONSTASCII_USTRINGPARAM("EndNotice")) 150 , sPropertyBeginNotice(RTL_CONSTASCII_USTRINGPARAM("BeginNotice")) 151 , sNumFormat(RTL_CONSTASCII_USTRINGPARAM("1")) 152 , sNumSync(RTL_CONSTASCII_USTRINGPARAM("false")) 153 , pAttrTokenMap(NULL) 154 , nOffset(0) 155 , nNumbering(FootnoteNumbering::PER_PAGE) 156 , bPosition(sal_False) 157 , bIsEndnote(sal_False) 158 { 159 sal_Int16 nLength = xAttrList->getLength(); 160 for(sal_Int16 nAttr = 0; nAttr < nLength; nAttr++) 161 { 162 OUString sLocalName; 163 sal_uInt16 nPrefix = GetImport().GetNamespaceMap(). 164 GetKeyByAttrName( xAttrList->getNameByIndex(nAttr), 165 &sLocalName ); 166 if( XML_NAMESPACE_TEXT == nPrefix && IsXMLToken( sLocalName, 167 XML_NOTE_CLASS ) ) 168 { 169 const OUString& rValue = xAttrList->getValueByIndex( nAttr ); 170 if( IsXMLToken( rValue, XML_ENDNOTE ) ) 171 { 172 bIsEndnote = sal_True; 173 SetFamily( XML_STYLE_FAMILY_TEXT_FOOTNOTECONFIG ); 174 } 175 break; 176 } 177 } 178 179 } 180 XMLFootnoteConfigurationImportContext::~XMLFootnoteConfigurationImportContext() 181 { 182 delete pAttrTokenMap; 183 } 184 185 enum XMLFtnConfigToken 186 { 187 XML_TOK_FTNCONFIG_CITATION_STYLENAME, 188 XML_TOK_FTNCONFIG_ANCHOR_STYLENAME, 189 XML_TOK_FTNCONFIG_DEFAULT_STYLENAME, 190 XML_TOK_FTNCONFIG_PAGE_STYLENAME, 191 XML_TOK_FTNCONFIG_OFFSET, 192 XML_TOK_FTNCONFIG_NUM_PREFIX, 193 XML_TOK_FTNCONFIG_NUM_SUFFIX, 194 XML_TOK_FTNCONFIG_NUM_FORMAT, 195 XML_TOK_FTNCONFIG_NUM_SYNC, 196 XML_TOK_FTNCONFIG_START_AT, 197 XML_TOK_FTNCONFIG_POSITION 198 }; 199 200 static __FAR_DATA SvXMLTokenMapEntry aTextFieldAttrTokenMap[] = 201 { 202 { XML_NAMESPACE_TEXT, XML_CITATION_STYLE_NAME, XML_TOK_FTNCONFIG_CITATION_STYLENAME }, 203 { XML_NAMESPACE_TEXT, XML_CITATION_BODY_STYLE_NAME, XML_TOK_FTNCONFIG_ANCHOR_STYLENAME }, 204 { XML_NAMESPACE_TEXT, XML_DEFAULT_STYLE_NAME, XML_TOK_FTNCONFIG_DEFAULT_STYLENAME }, 205 { XML_NAMESPACE_TEXT, XML_MASTER_PAGE_NAME, XML_TOK_FTNCONFIG_PAGE_STYLENAME }, 206 { XML_NAMESPACE_TEXT, XML_START_VALUE, XML_TOK_FTNCONFIG_OFFSET }, 207 { XML_NAMESPACE_STYLE, XML_NUM_PREFIX, XML_TOK_FTNCONFIG_NUM_PREFIX }, 208 { XML_NAMESPACE_STYLE, XML_NUM_SUFFIX, XML_TOK_FTNCONFIG_NUM_SUFFIX }, 209 { XML_NAMESPACE_STYLE, XML_NUM_FORMAT, XML_TOK_FTNCONFIG_NUM_FORMAT }, 210 { XML_NAMESPACE_STYLE, XML_NUM_LETTER_SYNC, XML_TOK_FTNCONFIG_NUM_SYNC }, 211 { XML_NAMESPACE_TEXT, XML_START_NUMBERING_AT, XML_TOK_FTNCONFIG_START_AT}, 212 { XML_NAMESPACE_TEXT, XML_FOOTNOTES_POSITION, XML_TOK_FTNCONFIG_POSITION}, 213 214 // for backwards compatibility with SRC630 & earlier 215 { XML_NAMESPACE_TEXT, XML_NUM_PREFIX, XML_TOK_FTNCONFIG_NUM_PREFIX }, 216 { XML_NAMESPACE_TEXT, XML_NUM_SUFFIX, XML_TOK_FTNCONFIG_NUM_SUFFIX }, 217 { XML_NAMESPACE_TEXT, XML_OFFSET, XML_TOK_FTNCONFIG_OFFSET }, 218 XML_TOKEN_MAP_END 219 }; 220 221 const SvXMLTokenMap& 222 XMLFootnoteConfigurationImportContext::GetFtnConfigAttrTokenMap() 223 { 224 if (NULL == pAttrTokenMap) 225 { 226 pAttrTokenMap = new SvXMLTokenMap(aTextFieldAttrTokenMap); 227 } 228 229 return *pAttrTokenMap; 230 } 231 232 static SvXMLEnumMapEntry __READONLY_DATA aFootnoteNumberingMap[] = 233 { 234 { XML_PAGE, FootnoteNumbering::PER_PAGE }, 235 { XML_CHAPTER, FootnoteNumbering::PER_CHAPTER }, 236 { XML_DOCUMENT, FootnoteNumbering::PER_DOCUMENT }, 237 { XML_TOKEN_INVALID, 0 }, 238 }; 239 240 void XMLFootnoteConfigurationImportContext::StartElement( 241 const Reference<XAttributeList> & xAttrList ) 242 { 243 sal_Int16 nLength = xAttrList->getLength(); 244 for(sal_Int16 nAttr = 0; nAttr < nLength; nAttr++) 245 { 246 OUString sLocalName; 247 sal_uInt16 nPrefix = GetImport().GetNamespaceMap(). 248 GetKeyByAttrName( xAttrList->getNameByIndex(nAttr), 249 &sLocalName ); 250 OUString sValue = xAttrList->getValueByIndex(nAttr); 251 switch (GetFtnConfigAttrTokenMap().Get(nPrefix, sLocalName)) 252 { 253 case XML_TOK_FTNCONFIG_CITATION_STYLENAME: 254 sCitationStyle = sValue; 255 break; 256 case XML_TOK_FTNCONFIG_ANCHOR_STYLENAME: 257 sAnchorStyle = sValue; 258 break; 259 case XML_TOK_FTNCONFIG_DEFAULT_STYLENAME: 260 sDefaultStyle = sValue; 261 break; 262 case XML_TOK_FTNCONFIG_PAGE_STYLENAME: 263 sPageStyle = sValue; 264 break; 265 case XML_TOK_FTNCONFIG_OFFSET: 266 { 267 sal_Int32 nTmp; 268 if (SvXMLUnitConverter::convertNumber(nTmp, sValue)) 269 { 270 nOffset = (sal_uInt16)nTmp; 271 } 272 break; 273 } 274 case XML_TOK_FTNCONFIG_NUM_PREFIX: 275 sPrefix = sValue; 276 break; 277 case XML_TOK_FTNCONFIG_NUM_SUFFIX: 278 sSuffix = sValue; 279 break; 280 case XML_TOK_FTNCONFIG_NUM_FORMAT: 281 sNumFormat = sValue; 282 break; 283 case XML_TOK_FTNCONFIG_NUM_SYNC: 284 sNumSync = sValue; 285 break; 286 case XML_TOK_FTNCONFIG_START_AT: 287 { 288 sal_uInt16 nTmp; 289 if (SvXMLUnitConverter::convertEnum(nTmp, sValue, 290 aFootnoteNumberingMap)) 291 { 292 nNumbering = nTmp; 293 } 294 break; 295 } 296 case XML_TOK_FTNCONFIG_POSITION: 297 bPosition = IsXMLToken( sValue, XML_DOCUMENT ); 298 break; 299 default: 300 ; // ignore 301 } 302 } 303 } 304 305 SvXMLImportContext *XMLFootnoteConfigurationImportContext::CreateChildContext( 306 sal_uInt16 nPrefix, 307 const OUString& rLocalName, 308 const Reference<XAttributeList> & xAttrList ) 309 { 310 SvXMLImportContext* pContext = NULL; 311 312 if (!bIsEndnote) 313 { 314 if (XML_NAMESPACE_TEXT == nPrefix) 315 { 316 if ( IsXMLToken( rLocalName, 317 XML_FOOTNOTE_CONTINUATION_NOTICE_FORWARD ) ) 318 { 319 pContext = new XMLFootnoteConfigHelper(GetImport(), 320 nPrefix, rLocalName, 321 *this, sal_False); 322 } 323 else if ( IsXMLToken( rLocalName, 324 XML_FOOTNOTE_CONTINUATION_NOTICE_BACKWARD ) ) 325 { 326 pContext = new XMLFootnoteConfigHelper(GetImport(), 327 nPrefix, rLocalName, 328 *this, sal_True); 329 } 330 // else: default context 331 } 332 // else: unknown namespace -> default context 333 } 334 // else: endnote -> default context 335 336 if (pContext == NULL) 337 { 338 // default: delegate to super class 339 pContext = SvXMLStyleContext::CreateChildContext(nPrefix, 340 rLocalName, 341 xAttrList); 342 } 343 344 return pContext; 345 } 346 347 348 // --> OD 2005-01-31 #i40597# - rename method <CreateAndInsertLate(..)> to 349 // <Finish(..)> 350 void XMLFootnoteConfigurationImportContext::Finish( sal_Bool bOverwrite ) 351 // <-- 352 { 353 354 if (bOverwrite) 355 { 356 if (bIsEndnote) 357 { 358 Reference<XEndnotesSupplier> xSupplier( 359 GetImport().GetModel(), UNO_QUERY); 360 if (xSupplier.is()) 361 { 362 ProcessSettings(xSupplier->getEndnoteSettings()); 363 } 364 } 365 else 366 { 367 Reference<XFootnotesSupplier> xSupplier( 368 GetImport().GetModel(), UNO_QUERY); 369 if (xSupplier.is()) 370 { 371 ProcessSettings(xSupplier->getFootnoteSettings()); 372 } 373 } 374 } 375 // else: ignore (there's only one configuration, so we can only overwrite) 376 } 377 378 void XMLFootnoteConfigurationImportContext::ProcessSettings( 379 const Reference<XPropertySet> & rConfig) 380 { 381 Any aAny; 382 383 if (sCitationStyle.getLength() > 0) 384 { 385 aAny <<= GetImport().GetStyleDisplayName( 386 XML_STYLE_FAMILY_TEXT_TEXT, sCitationStyle ); 387 rConfig->setPropertyValue(sPropertyCharStyleName, aAny); 388 } 389 390 if (sAnchorStyle.getLength() > 0) 391 { 392 aAny <<= GetImport().GetStyleDisplayName( 393 XML_STYLE_FAMILY_TEXT_TEXT, sAnchorStyle ); 394 rConfig->setPropertyValue(sPropertyAnchorCharStyleName, aAny); 395 } 396 397 if (sPageStyle.getLength() > 0) 398 { 399 aAny <<= GetImport().GetStyleDisplayName( 400 XML_STYLE_FAMILY_MASTER_PAGE, sPageStyle ); 401 rConfig->setPropertyValue(sPropertyPageStyleName, aAny); 402 } 403 404 if (sDefaultStyle.getLength() > 0) 405 { 406 aAny <<= GetImport().GetStyleDisplayName( 407 XML_STYLE_FAMILY_TEXT_PARAGRAPH, sDefaultStyle ); 408 rConfig->setPropertyValue(sPropertyParagraphStyleName, aAny); 409 } 410 411 aAny <<= sPrefix; 412 rConfig->setPropertyValue(sPropertyPrefix, aAny); 413 414 aAny <<= sSuffix; 415 rConfig->setPropertyValue(sPropertySuffix, aAny); 416 417 sal_Int16 nNumType = NumberingType::ARABIC; 418 GetImport().GetMM100UnitConverter().convertNumFormat( nNumType, sNumFormat, 419 sNumSync ); 420 // #i61399: Corrupt file? It contains "Bullet" as numbering style for footnotes. 421 // Okay, even it seems to be corrupt, we will oversee this and set the style to ARABIC 422 if( NumberingType::CHAR_SPECIAL == nNumType ) 423 nNumType = NumberingType::ARABIC; 424 425 aAny <<= nNumType; 426 rConfig->setPropertyValue(sPropertyNumberingType, aAny); 427 428 aAny <<= nOffset; 429 rConfig->setPropertyValue(sPropertyStartAt, aAny); 430 431 if (!bIsEndnote) 432 { 433 aAny.setValue(&bPosition, ::getBooleanCppuType()); 434 rConfig->setPropertyValue(sPropertyPositionEndOfDoc, aAny); 435 436 aAny <<= nNumbering; 437 rConfig->setPropertyValue(sPropertyFootnoteCounting, aAny); 438 439 aAny <<= sEndNotice; 440 rConfig->setPropertyValue(sPropertyEndNotice, aAny); 441 442 aAny <<= sBeginNotice; 443 rConfig->setPropertyValue(sPropertyBeginNotice, aAny); 444 } 445 } 446 447 void XMLFootnoteConfigurationImportContext::SetBeginNotice( 448 OUString sText) 449 { 450 sBeginNotice = sText; 451 } 452 453 void XMLFootnoteConfigurationImportContext::SetEndNotice( 454 OUString sText) 455 { 456 sEndNotice = sText; 457 } 458