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