/src/libreoffice/xmloff/source/text/XMLFootnoteImportContext.cxx
Line | Count | Source |
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 <comphelper/diagnose_ex.hxx> |
23 | | #include <rtl/ustring.hxx> |
24 | | #include <sal/log.hxx> |
25 | | #include <xmloff/xmlimp.hxx> |
26 | | #include <xmloff/txtimp.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/text/XTextContent.hpp> |
34 | | #include <com/sun/star/beans/XPropertySet.hpp> |
35 | | #include <com/sun/star/lang/XMultiServiceFactory.hpp> |
36 | | #include <com/sun/star/text/XFootnote.hpp> |
37 | | |
38 | | |
39 | | using namespace ::com::sun::star::uno; |
40 | | using namespace ::com::sun::star::text; |
41 | | using namespace ::com::sun::star::lang; |
42 | | using namespace ::com::sun::star::beans; |
43 | | using namespace ::com::sun::star::xml::sax; |
44 | | using namespace ::xmloff::token; |
45 | | |
46 | | XMLFootnoteImportContext::XMLFootnoteImportContext( |
47 | | SvXMLImport& rImport, |
48 | | XMLTextImportHelper& rHlp ) |
49 | 517 | : SvXMLImportContext(rImport) |
50 | 517 | , mbListContextPushed(false) |
51 | 517 | , rHelper(rHlp) |
52 | 517 | { |
53 | 517 | } |
54 | | |
55 | | void XMLFootnoteImportContext::startFastElement( |
56 | | sal_Int32 /*nElement*/, |
57 | | const css::uno::Reference< css::xml::sax::XFastAttributeList >& xAttrList ) |
58 | 517 | { |
59 | | // create footnote |
60 | 517 | Reference<XMultiServiceFactory> xFactory(GetImport().GetModel(), |
61 | 517 | UNO_QUERY); |
62 | 517 | if( !xFactory.is() ) |
63 | 0 | return; |
64 | | |
65 | | // create endnote or footnote |
66 | 517 | bool bIsEndnote = false; |
67 | 517 | for( auto& aIter : sax_fastparser::castToFastAttributeList(xAttrList) ) |
68 | 982 | { |
69 | 982 | if( aIter.getToken() == XML_ELEMENT(TEXT, XML_NOTE_CLASS) ) |
70 | 494 | { |
71 | 494 | if( IsXMLToken( aIter, XML_ENDNOTE ) ) |
72 | 28 | bIsEndnote = true; |
73 | 494 | break; |
74 | 494 | } |
75 | 982 | } |
76 | | |
77 | 517 | Reference<XInterface> xIfc = xFactory->createInstance( |
78 | 517 | bIsEndnote ? |
79 | 28 | u"com.sun.star.text.Endnote"_ustr : |
80 | 517 | u"com.sun.star.text.Footnote"_ustr ); |
81 | | |
82 | | // attach footnote to document |
83 | 517 | Reference<XTextContent> xTextContent(xIfc, UNO_QUERY); |
84 | 517 | rHelper.InsertTextContent(xTextContent); |
85 | | |
86 | | // process id attribute |
87 | 517 | for( auto& aIter : sax_fastparser::castToFastAttributeList(xAttrList) ) |
88 | 507 | { |
89 | 507 | if( aIter.getToken() == XML_ELEMENT(TEXT, XML_ID) ) |
90 | 488 | { |
91 | | // get ID ... |
92 | 488 | Reference<XPropertySet> xPropertySet(xTextContent, UNO_QUERY); |
93 | 488 | Any aAny =xPropertySet->getPropertyValue(u"ReferenceId"_ustr); |
94 | 488 | sal_Int16 nID = 0; |
95 | 488 | aAny >>= nID; |
96 | | |
97 | | // ... and insert into map |
98 | 488 | rHelper.InsertFootnoteID( aIter.toString(), nID); |
99 | 488 | break; |
100 | 488 | } |
101 | 507 | } |
102 | | |
103 | | // save old cursor and install new one |
104 | 517 | xOldCursor = rHelper.GetCursor(); |
105 | 517 | Reference<XText> xText(xTextContent, UNO_QUERY); |
106 | 517 | try |
107 | 517 | { |
108 | | // May fail e.g. for a nested footnote, which is formally a valid ODF, but is not supported |
109 | 517 | rHelper.SetCursor(xText->createTextCursor()); |
110 | 517 | } |
111 | 517 | catch (css::uno::RuntimeException&) |
112 | 517 | { |
113 | 4 | TOOLS_WARN_EXCEPTION("xmloff.text", "skipping the footnote: caught"); |
114 | 4 | mbIsValid = false; |
115 | 4 | } |
116 | | |
117 | | // remember old list item and block (#89891#) and reset them |
118 | | // for the footnote |
119 | 514 | rHelper.PushListContext(); |
120 | 514 | mbListContextPushed = true; |
121 | | |
122 | | // remember footnote (for CreateChildContext) |
123 | 514 | xFootnote.set(xTextContent, UNO_QUERY); |
124 | | |
125 | | // else: ignore footnote! Content will be merged into document. |
126 | 514 | } |
127 | | |
128 | | void XMLFootnoteImportContext::endFastElement(sal_Int32 ) |
129 | 471 | { |
130 | | // get rid of last dummy paragraph |
131 | 471 | rHelper.DeleteParagraph(); |
132 | | |
133 | | // reinstall old cursor |
134 | 471 | rHelper.SetCursor(xOldCursor); |
135 | | |
136 | | // reinstall old list item |
137 | 471 | if (mbListContextPushed) { |
138 | 471 | rHelper.PopListContext(); |
139 | 471 | } |
140 | 471 | } |
141 | | |
142 | | css::uno::Reference< css::xml::sax::XFastContextHandler > XMLFootnoteImportContext::createFastChildContext( |
143 | | sal_Int32 nElement, const css::uno::Reference< css::xml::sax::XFastAttributeList >& xAttrList ) |
144 | 1.01k | { |
145 | 1.01k | if (!mbIsValid) |
146 | 8 | return {}; |
147 | 1.00k | SvXMLImportContextRef xContext; |
148 | | |
149 | 1.00k | switch(nElement) |
150 | 1.00k | { |
151 | 497 | case XML_ELEMENT(TEXT, XML_NOTE_CITATION): |
152 | 497 | { |
153 | | // little hack: we only care for one attribute of the citation |
154 | | // element. We handle that here, and then return a |
155 | | // default context. |
156 | 497 | for( auto& aIter : sax_fastparser::castToFastAttributeList(xAttrList) ) |
157 | 0 | { |
158 | 0 | if ( aIter.getToken() == XML_ELEMENT(TEXT, XML_LABEL) ) |
159 | 0 | xFootnote->setLabel(aIter.toString()); |
160 | 0 | } |
161 | | |
162 | | // ignore content: return default context |
163 | 497 | break; |
164 | 0 | } |
165 | | |
166 | 484 | case XML_ELEMENT(TEXT, XML_NOTE_BODY): |
167 | | // return footnote body |
168 | 484 | xContext = new XMLFootnoteBodyImportContext(GetImport()); |
169 | 484 | break; |
170 | | |
171 | 21 | default: |
172 | 21 | XMLOFF_WARN_UNKNOWN_ELEMENT("xmloff", nElement); |
173 | 1.00k | } |
174 | | |
175 | 1.00k | return xContext; |
176 | 1.00k | } |
177 | | |
178 | | /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |