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