1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
4 *
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 *
9 * This file incorporates work covered by the following license notice:
10 *
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 */
19
20 #include "XMLFootnoteImportContext.hxx"
21
22 #include <rtl/ustring.hxx>
23 #include <sal/log.hxx>
24 #include <xmloff/xmlimp.hxx>
25 #include <xmloff/txtimp.hxx>
26 #include <xmloff/namespacemap.hxx>
27 #include <xmloff/xmlnamespace.hxx>
28 #include <xmloff/xmltoken.hxx>
29
30 #include "XMLFootnoteBodyImportContext.hxx"
31
32 #include <com/sun/star/frame/XModel.hpp>
33 #include <com/sun/star/xml/sax/XAttributeList.hpp>
34 #include <com/sun/star/text/XTextContent.hpp>
35 #include <com/sun/star/beans/XPropertySet.hpp>
36 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
37 #include <com/sun/star/text/XFootnote.hpp>
38
39
40 using namespace ::com::sun::star::uno;
41 using namespace ::com::sun::star::text;
42 using namespace ::com::sun::star::lang;
43 using namespace ::com::sun::star::beans;
44 using namespace ::com::sun::star::xml::sax;
45 using namespace ::xmloff::token;
46
XMLFootnoteImportContext(SvXMLImport & rImport,XMLTextImportHelper & rHlp)47 XMLFootnoteImportContext::XMLFootnoteImportContext(
48 SvXMLImport& rImport,
49 XMLTextImportHelper& rHlp )
50 : SvXMLImportContext(rImport)
51 , mbListContextPushed(false)
52 , rHelper(rHlp)
53 {
54 }
55
startFastElement(sal_Int32,const css::uno::Reference<css::xml::sax::XFastAttributeList> & xAttrList)56 void XMLFootnoteImportContext::startFastElement(
57 sal_Int32 /*nElement*/,
58 const css::uno::Reference< css::xml::sax::XFastAttributeList >& xAttrList )
59 {
60 // create footnote
61 Reference<XMultiServiceFactory> xFactory(GetImport().GetModel(),
62 UNO_QUERY);
63 if( !xFactory.is() )
64 return;
65
66 // create endnote or footnote
67 bool bIsEndnote = false;
68 for( auto& aIter : sax_fastparser::castToFastAttributeList(xAttrList) )
69 {
70 if( aIter.getToken() == XML_ELEMENT(TEXT, XML_NOTE_CLASS) )
71 {
72 if( IsXMLToken( aIter, XML_ENDNOTE ) )
73 bIsEndnote = true;
74 break;
75 }
76 }
77
78 Reference<XInterface> xIfc = xFactory->createInstance(
79 bIsEndnote ?
80 OUString("com.sun.star.text.Endnote") :
81 OUString("com.sun.star.text.Footnote") );
82
83 // attach footnote to document
84 Reference<XTextContent> xTextContent(xIfc, UNO_QUERY);
85 rHelper.InsertTextContent(xTextContent);
86
87 // process id attribute
88 for( auto& aIter : sax_fastparser::castToFastAttributeList(xAttrList) )
89 {
90 if( aIter.getToken() == XML_ELEMENT(TEXT, XML_ID) )
91 {
92 // get ID ...
93 Reference<XPropertySet> xPropertySet(xTextContent, UNO_QUERY);
94 Any aAny =xPropertySet->getPropertyValue("ReferenceId");
95 sal_Int16 nID = 0;
96 aAny >>= nID;
97
98 // ... and insert into map
99 rHelper.InsertFootnoteID( aIter.toString(), nID);
100 break;
101 }
102 }
103
104 // save old cursor and install new one
105 xOldCursor = rHelper.GetCursor();
106 Reference<XText> xText(xTextContent, UNO_QUERY);
107 rHelper.SetCursor(xText->createTextCursor());
108
109 // remember old list item and block (#89891#) and reset them
110 // for the footnote
111 rHelper.PushListContext();
112 mbListContextPushed = true;
113
114 // remember footnote (for CreateChildContext)
115 Reference<XFootnote> xNote(xTextContent, UNO_QUERY);
116 xFootnote = xNote;
117
118 // else: ignore footnote! Content will be merged into document.
119 }
120
endFastElement(sal_Int32)121 void XMLFootnoteImportContext::endFastElement(sal_Int32 )
122 {
123 // get rid of last dummy paragraph
124 rHelper.DeleteParagraph();
125
126 // reinstall old cursor
127 rHelper.SetCursor(xOldCursor);
128
129 // reinstall old list item
130 if (mbListContextPushed) {
131 rHelper.PopListContext();
132 }
133 }
134
createFastChildContext(sal_Int32 nElement,const css::uno::Reference<css::xml::sax::XFastAttributeList> & xAttrList)135 css::uno::Reference< css::xml::sax::XFastContextHandler > XMLFootnoteImportContext::createFastChildContext(
136 sal_Int32 nElement, const css::uno::Reference< css::xml::sax::XFastAttributeList >& xAttrList )
137 {
138 SvXMLImportContextRef xContext;
139
140 switch(nElement)
141 {
142 case XML_ELEMENT(TEXT, XML_NOTE_CITATION):
143 {
144 // little hack: we only care for one attribute of the citation
145 // element. We handle that here, and then return a
146 // default context.
147 for( auto& aIter : sax_fastparser::castToFastAttributeList(xAttrList) )
148 {
149 if ( aIter.getToken() == XML_ELEMENT(TEXT, XML_LABEL) )
150 xFootnote->setLabel(aIter.toString());
151 }
152
153 // ignore content: return default context
154 break;
155 }
156
157 case XML_ELEMENT(TEXT, XML_NOTE_BODY):
158 // return footnote body
159 xContext = new XMLFootnoteBodyImportContext(GetImport());
160 break;
161
162 default:
163 XMLOFF_WARN_UNKNOWN_ELEMENT("xmloff", nElement);
164 }
165
166 return xContext;
167 }
168
169 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
170