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 "XMLFootnoteImportContext.hxx" 33 34 #include <rtl/ustring.hxx> 35 #include <tools/debug.hxx> 36 #include <xmloff/xmlimp.hxx> 37 #include <xmloff/txtimp.hxx> 38 #include <xmloff/nmspmap.hxx> 39 #include "xmloff/xmlnmspe.hxx" 40 #include <xmloff/xmltoken.hxx> 41 42 #include "XMLFootnoteBodyImportContext.hxx" 43 #include "XMLTextListBlockContext.hxx" 44 #include "XMLTextListItemContext.hxx" 45 46 #include <com/sun/star/xml/sax/XAttributeList.hpp> 47 #include <com/sun/star/text/XTextContent.hpp> 48 #include <com/sun/star/beans/XPropertySet.hpp> 49 #include <com/sun/star/lang/XMultiServiceFactory.hpp> 50 #include <com/sun/star/text/XFootnote.hpp> 51 52 53 using ::rtl::OUString; 54 using ::rtl::OUStringBuffer; 55 56 using namespace ::com::sun::star::uno; 57 using namespace ::com::sun::star::text; 58 using namespace ::com::sun::star::lang; 59 using namespace ::com::sun::star::beans; 60 using namespace ::com::sun::star::xml::sax; 61 using namespace ::xmloff::token; 62 63 TYPEINIT1(XMLFootnoteImportContext, SvXMLImportContext); 64 65 const sal_Char sAPI_service_footnote[] = "com.sun.star.text.Footnote"; 66 const sal_Char sAPI_service_endnote[] = "com.sun.star.text.Endnote"; 67 68 enum XMLFootnoteChildToken { 69 XML_TOK_FTN_NOTE_CITATION, 70 XML_TOK_FTN_NOTE_BODY 71 }; 72 73 static __FAR_DATA SvXMLTokenMapEntry aFootnoteChildTokenMap[] = 74 { 75 { XML_NAMESPACE_TEXT, XML_NOTE_CITATION, 76 XML_TOK_FTN_NOTE_CITATION }, 77 { XML_NAMESPACE_TEXT, XML_NOTE_BODY, XML_TOK_FTN_NOTE_BODY }, 78 XML_TOKEN_MAP_END 79 }; 80 81 82 XMLFootnoteImportContext::XMLFootnoteImportContext( 83 SvXMLImport& rImport, 84 XMLTextImportHelper& rHlp, 85 sal_uInt16 nPrfx, 86 const OUString& rLocalName ) 87 : SvXMLImportContext(rImport, nPrfx, rLocalName) 88 , sPropertyReferenceId(RTL_CONSTASCII_USTRINGPARAM("ReferenceId")) 89 , mbListContextPushed(false) 90 , rHelper(rHlp) 91 { 92 } 93 94 void XMLFootnoteImportContext::StartElement( 95 const Reference<XAttributeList> & xAttrList) 96 { 97 // create footnote 98 Reference<XMultiServiceFactory> xFactory(GetImport().GetModel(), 99 UNO_QUERY); 100 if( xFactory.is() ) 101 { 102 // create endnote or footnote 103 sal_Bool bIsEndnote = sal_False; 104 sal_Int16 nLength = xAttrList->getLength(); 105 for(sal_Int16 nAttr1 = 0; nAttr1 < nLength; nAttr1++) 106 { 107 OUString sLocalName; 108 sal_uInt16 nPrefix = GetImport().GetNamespaceMap(). 109 GetKeyByAttrName( xAttrList->getNameByIndex(nAttr1), 110 &sLocalName ); 111 if( XML_NAMESPACE_TEXT == nPrefix && IsXMLToken( sLocalName, 112 XML_NOTE_CLASS ) ) 113 { 114 const OUString& rValue = xAttrList->getValueByIndex( nAttr1 ); 115 if( IsXMLToken( rValue, XML_ENDNOTE ) ) 116 bIsEndnote = sal_True; 117 break; 118 } 119 } 120 121 Reference<XInterface> xIfc = xFactory->createInstance( 122 bIsEndnote ? 123 OUString(RTL_CONSTASCII_USTRINGPARAM(sAPI_service_endnote)) : 124 OUString(RTL_CONSTASCII_USTRINGPARAM(sAPI_service_footnote)) ); 125 126 // attach footnote to document 127 Reference<XTextContent> xTextContent(xIfc, UNO_QUERY); 128 rHelper.InsertTextContent(xTextContent); 129 130 // process id attribute 131 for(sal_Int16 nAttr2 = 0; nAttr2 < nLength; nAttr2++) 132 { 133 OUString sLocalName; 134 sal_uInt16 nPrefix = GetImport().GetNamespaceMap(). 135 GetKeyByAttrName( xAttrList->getNameByIndex(nAttr2), 136 &sLocalName ); 137 138 if ( (XML_NAMESPACE_TEXT == nPrefix) && 139 IsXMLToken( sLocalName, XML_ID ) ) 140 { 141 // get ID ... 142 Reference<XPropertySet> xPropertySet(xTextContent, UNO_QUERY); 143 Any aAny =xPropertySet->getPropertyValue(sPropertyReferenceId); 144 sal_Int16 nID = 0; 145 aAny >>= nID; 146 147 // ... and insert into map 148 rHelper.InsertFootnoteID( 149 xAttrList->getValueByIndex(nAttr2), 150 nID); 151 } 152 } 153 154 // save old cursor and install new one 155 xOldCursor = rHelper.GetCursor(); 156 Reference<XText> xText(xTextContent, UNO_QUERY); 157 rHelper.SetCursor(xText->createTextCursor()); 158 159 // remember old list item and block (#89891#) and reset them 160 // for the footnote 161 rHelper.PushListContext(); 162 mbListContextPushed = true; 163 164 // remember footnote (for CreateChildContext) 165 Reference<XFootnote> xNote(xTextContent, UNO_QUERY); 166 xFootnote = xNote; 167 } 168 // else: ignore footnote! Content will be merged into document. 169 } 170 171 void XMLFootnoteImportContext::Characters(const OUString&) 172 { 173 // ignore characters! Text must be contained in paragraphs! 174 // rHelper.InsertString(rString); 175 } 176 177 void XMLFootnoteImportContext::EndElement() 178 { 179 // get rid of last dummy paragraph 180 rHelper.DeleteParagraph(); 181 182 // reinstall old cursor 183 rHelper.SetCursor(xOldCursor); 184 185 // reinstall old list item 186 if (mbListContextPushed) { 187 rHelper.PopListContext(); 188 } 189 } 190 191 192 SvXMLImportContext *XMLFootnoteImportContext::CreateChildContext( 193 sal_uInt16 p_nPrefix, 194 const OUString& rLocalName, 195 const Reference<XAttributeList> & xAttrList ) 196 { 197 SvXMLImportContext* pContext = NULL; 198 199 SvXMLTokenMap aTokenMap(aFootnoteChildTokenMap); 200 201 switch(aTokenMap.Get(p_nPrefix, rLocalName)) 202 { 203 case XML_TOK_FTN_NOTE_CITATION: 204 { 205 // little hack: we only care for one attribute of the citation 206 // element. We handle that here, and then return a 207 // default context. 208 sal_Int16 nLength = xAttrList->getLength(); 209 for(sal_Int16 nAttr = 0; nAttr < nLength; nAttr++) 210 { 211 OUString sLocalName; 212 sal_uInt16 nPrefix = GetImport().GetNamespaceMap(). 213 GetKeyByAttrName( xAttrList->getNameByIndex(nAttr), 214 &sLocalName ); 215 216 if ( (nPrefix == XML_NAMESPACE_TEXT) && 217 IsXMLToken( sLocalName, XML_LABEL ) ) 218 { 219 xFootnote->setLabel(xAttrList->getValueByIndex(nAttr)); 220 } 221 } 222 223 // ignore content: return default context 224 pContext = new SvXMLImportContext(GetImport(), 225 p_nPrefix, rLocalName); 226 break; 227 } 228 229 case XML_TOK_FTN_NOTE_BODY: 230 // return footnote body 231 pContext = new XMLFootnoteBodyImportContext(GetImport(), 232 p_nPrefix, rLocalName); 233 break; 234 default: 235 // default: 236 pContext = SvXMLImportContext::CreateChildContext(p_nPrefix, 237 rLocalName, 238 xAttrList); 239 break; 240 } 241 242 return pContext; 243 } 244