LanguageTool: don't crash if REST protocol isn't set
[LibreOffice.git] / xmloff / source / text / XMLIndexTOCContext.cxx
blobe7235f093efa0ac8133b36ac7d1b55dc23993afc
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
20 #include "XMLIndexTOCContext.hxx"
21 #include <com/sun/star/frame/XModel.hpp>
22 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
23 #include <com/sun/star/lang/IllegalArgumentException.hpp>
24 #include <com/sun/star/uno/XInterface.hpp>
25 #include <com/sun/star/text/XTextContent.hpp>
26 #include <com/sun/star/beans/XPropertySet.hpp>
27 #include <sax/tools/converter.hxx>
28 #include <sal/log.hxx>
29 #include "XMLIndexTOCSourceContext.hxx"
30 #include "XMLIndexObjectSourceContext.hxx"
31 #include "XMLIndexAlphabeticalSourceContext.hxx"
32 #include "XMLIndexUserSourceContext.hxx"
33 #include "XMLIndexBibliographySourceContext.hxx"
34 #include "XMLIndexTableSourceContext.hxx"
35 #include "XMLIndexIllustrationSourceContext.hxx"
36 #include "XMLIndexBodyContext.hxx"
37 #include <xmloff/xmlictxt.hxx>
38 #include <xmloff/xmlimp.hxx>
39 #include <xmloff/txtimp.hxx>
40 #include <xmloff/namespacemap.hxx>
41 #include <xmloff/xmlnamespace.hxx>
42 #include <xmloff/xmltoken.hxx>
43 #include <xmloff/prstylei.hxx>
44 #include <xmloff/xmlerror.hxx>
45 #include <xmloff/xmluconv.hxx>
46 #include <xmloff/xmlement.hxx>
47 #include <rtl/ustring.hxx>
48 #include <osl/diagnose.h>
51 using namespace ::com::sun::star::uno;
52 using namespace ::com::sun::star::text;
53 using namespace ::xmloff::token;
55 using ::com::sun::star::beans::XPropertySet;
56 using ::com::sun::star::uno::Reference;
57 using ::com::sun::star::xml::sax::XAttributeList;
58 using ::com::sun::star::lang::XMultiServiceFactory;
59 using ::com::sun::star::lang::IllegalArgumentException;
62 static const char* aIndexServiceMap[] =
64 "com.sun.star.text.ContentIndex",
65 "com.sun.star.text.DocumentIndex",
66 "com.sun.star.text.TableIndex",
67 "com.sun.star.text.ObjectIndex",
68 "com.sun.star.text.Bibliography",
69 "com.sun.star.text.UserIndex",
70 "com.sun.star.text.IllustrationsIndex"
73 const XMLTokenEnum aIndexSourceElementMap[] =
75 XML_TABLE_OF_CONTENT_SOURCE,
76 XML_ALPHABETICAL_INDEX_SOURCE,
77 XML_TABLE_INDEX_SOURCE,
78 XML_OBJECT_INDEX_SOURCE,
79 XML_BIBLIOGRAPHY_SOURCE,
80 XML_USER_INDEX_SOURCE,
81 XML_ILLUSTRATION_INDEX_SOURCE
84 SvXMLEnumMapEntry<IndexTypeEnum> const aIndexTypeMap[] =
86 { XML_TABLE_OF_CONTENT, TEXT_INDEX_TOC },
87 { XML_ALPHABETICAL_INDEX, TEXT_INDEX_ALPHABETICAL },
88 { XML_TABLE_INDEX, TEXT_INDEX_TABLE },
89 { XML_OBJECT_INDEX, TEXT_INDEX_OBJECT },
90 { XML_BIBLIOGRAPHY, TEXT_INDEX_BIBLIOGRAPHY },
91 { XML_USER_INDEX, TEXT_INDEX_USER },
92 { XML_ILLUSTRATION_INDEX, TEXT_INDEX_ILLUSTRATION },
93 { XML_TOKEN_INVALID, IndexTypeEnum(0) }
97 XMLIndexTOCContext::XMLIndexTOCContext(SvXMLImport& rImport,
98 sal_Int32 nElement)
99 : SvXMLImportContext(rImport)
100 , eIndexType(TEXT_INDEX_UNKNOWN)
101 , bValid(false)
103 if (IsTokenInNamespace(nElement, XML_NAMESPACE_TEXT))
105 if (SvXMLUnitConverter::convertEnum(eIndexType, SvXMLImport::getNameFromToken(nElement), aIndexTypeMap))
107 // check for array index:
108 OSL_ENSURE(unsigned(eIndexType) < (SAL_N_ELEMENTS(aIndexServiceMap)), "index out of range");
109 OSL_ENSURE(SAL_N_ELEMENTS(aIndexServiceMap) ==
110 SAL_N_ELEMENTS(aIndexSourceElementMap),
111 "service and source element maps must be same size");
112 bValid = true;
117 XMLIndexTOCContext::~XMLIndexTOCContext()
121 void XMLIndexTOCContext::startFastElement(
122 sal_Int32 nElement,
123 const css::uno::Reference< css::xml::sax::XFastAttributeList >& xAttrList )
125 if (!bValid)
126 return;
128 // find text:style-name attribute and set section style
129 // find text:protected and set value
130 // find text:name and set value (if not empty)
131 bool bProtected = false;
132 OUString sIndexName;
133 OUString sXmlId;
134 XMLPropStyleContext* pStyle(nullptr);
135 for( auto& aIter : sax_fastparser::castToFastAttributeList(xAttrList) )
137 switch(aIter.getToken())
139 case XML_ELEMENT(TEXT, XML_STYLE_NAME):
141 pStyle = GetImport().GetTextImport()->FindSectionStyle(
142 aIter.toString());
143 break;
145 case XML_ELEMENT(TEXT, XML_PROTECTED):
147 bool bTmp(false);
148 if (::sax::Converter::convertBool(bTmp, aIter.toView()))
150 bProtected = bTmp;
152 break;
154 case XML_ELEMENT(TEXT, XML_NAME):
156 sIndexName = aIter.toString();
157 break;
159 case XML_ELEMENT(XML, XML_ID):
161 sXmlId = aIter.toString();
162 break;
164 default:
165 XMLOFF_WARN_UNKNOWN("xmloff", aIter);
169 // create table of content (via MultiServiceFactory)
170 Reference<XMultiServiceFactory> xFactory(GetImport().GetModel(),
171 UNO_QUERY);
172 if( xFactory.is() )
174 Reference<XInterface> xIfc =
175 xFactory->createInstance(
176 OUString::createFromAscii(aIndexServiceMap[eIndexType]));
177 if( xIfc.is() )
179 // get Property set
180 Reference<XPropertySet> xPropSet(xIfc, UNO_QUERY);
181 xTOCPropertySet = xPropSet;
183 // insert section
184 // a) insert section
185 // The inserted index consists of an empty paragraph
186 // only, as well as an empty paragraph *after* the index
187 // b) insert marker after index, and put Cursor inside of the
188 // index
190 // preliminaries
191 #ifndef DBG_UTIL
192 OUString const sMarker(" ");
193 #else
194 OUString const sMarker("Y");
195 #endif
196 rtl::Reference<XMLTextImportHelper> rImport =
197 GetImport().GetTextImport();
199 // a) insert index
200 Reference<XTextContent> xTextContent(xIfc, UNO_QUERY);
203 GetImport().GetTextImport()->InsertTextContent(
204 xTextContent);
206 catch(const IllegalArgumentException& e)
208 // illegal argument? Then we can't accept indices here!
209 Sequence<OUString> aSeq { SvXMLImport::getNameFromToken(nElement) };
210 GetImport().SetError(
211 XMLERROR_FLAG_ERROR | XMLERROR_NO_INDEX_ALLOWED_HERE,
212 aSeq, e.Message, nullptr );
214 // set bValid to false, and return prematurely
215 bValid = false;
216 return;
219 // xml:id for RDF metadata
220 GetImport().SetXmlId(xIfc, sXmlId);
222 // b) insert marker and move cursor
223 rImport->InsertString(sMarker);
224 rImport->GetCursor()->goLeft(2, false);
228 // finally, check for redlines that should start at
229 // the section start node
230 if( bValid )
231 GetImport().GetTextImport()->RedlineAdjustStartNodeCursor();
233 if (pStyle != nullptr)
235 pStyle->FillPropertySet( xTOCPropertySet );
238 xTOCPropertySet->setPropertyValue( "IsProtected", Any(bProtected) );
240 if (!sIndexName.isEmpty())
242 xTOCPropertySet->setPropertyValue( "Name", Any(sIndexName) );
247 void XMLIndexTOCContext::endFastElement(sal_Int32 )
249 // complete import of index by removing the markers (if the index
250 // was actually inserted, that is)
251 if( !bValid )
252 return;
254 // preliminaries
255 rtl::Reference<XMLTextImportHelper> rHelper= GetImport().GetTextImport();
257 // get rid of last paragraph (unless it's the only paragraph)
258 rHelper->GetCursor()->goRight(1, false);
259 if( xBodyContextRef.is() && xBodyContextRef->HasContent() )
261 rHelper->GetCursor()->goLeft(1, true);
262 rHelper->GetText()->insertString(rHelper->GetCursorAsRange(),
263 "", true);
266 // and delete second marker
267 rHelper->GetCursor()->goRight(1, true);
268 rHelper->GetText()->insertString(rHelper->GetCursorAsRange(),
269 "", true);
271 // check for Redlines on our end node
272 GetImport().GetTextImport()->RedlineAdjustStartNodeCursor();
275 css::uno::Reference< css::xml::sax::XFastContextHandler > XMLIndexTOCContext::createFastChildContext(
276 sal_Int32 nElement,
277 const css::uno::Reference< css::xml::sax::XFastAttributeList >& )
279 SvXMLImportContextRef xContext;
281 // not valid -> ignore
282 if (!bValid)
283 return nullptr;
285 if (nElement == XML_ELEMENT(TEXT, XML_INDEX_BODY) )
287 rtl::Reference<XMLIndexBodyContext> xNewBodyContext = new XMLIndexBodyContext(GetImport());
288 xContext = xNewBodyContext;
289 if ( !xBodyContextRef.is() || !xBodyContextRef->HasContent() )
291 xBodyContextRef = xNewBodyContext;
294 else if (nElement == XML_ELEMENT(TEXT, aIndexSourceElementMap[eIndexType]))
296 // instantiate source context for the appropriate index type
297 switch (eIndexType)
299 case TEXT_INDEX_TOC:
300 xContext = new XMLIndexTOCSourceContext(
301 GetImport(), xTOCPropertySet);
302 break;
304 case TEXT_INDEX_OBJECT:
305 xContext = new XMLIndexObjectSourceContext(
306 GetImport(), xTOCPropertySet);
307 break;
309 case TEXT_INDEX_ALPHABETICAL:
310 xContext = new XMLIndexAlphabeticalSourceContext(
311 GetImport(), xTOCPropertySet);
312 break;
314 case TEXT_INDEX_USER:
315 xContext = new XMLIndexUserSourceContext(
316 GetImport(), xTOCPropertySet);
317 break;
319 case TEXT_INDEX_BIBLIOGRAPHY:
320 xContext = new XMLIndexBibliographySourceContext(
321 GetImport(), xTOCPropertySet);
322 break;
324 case TEXT_INDEX_TABLE:
325 xContext = new XMLIndexTableSourceContext(
326 GetImport(), xTOCPropertySet);
327 break;
329 case TEXT_INDEX_ILLUSTRATION:
330 xContext = new XMLIndexIllustrationSourceContext(
331 GetImport(), xTOCPropertySet);
332 break;
334 default:
335 OSL_FAIL("index type not implemented");
336 break;
339 // else: ignore
341 return xContext;
344 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */