LibreOffice Module xmloff (master) 1
XMLIndexTOCContext.cxx
Go to the documentation of this file.
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
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>
28#include <sal/log.hxx>
37#include <xmloff/xmlictxt.hxx>
38#include <xmloff/xmlimp.hxx>
39#include <xmloff/txtimp.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>
49
50
51using namespace ::com::sun::star::uno;
52using namespace ::com::sun::star::text;
53using namespace ::xmloff::token;
54
55using ::com::sun::star::beans::XPropertySet;
56using ::com::sun::star::uno::Reference;
57using ::com::sun::star::lang::XMultiServiceFactory;
58using ::com::sun::star::lang::IllegalArgumentException;
59
60
61static const char* aIndexServiceMap[] =
62{
63 "com.sun.star.text.ContentIndex",
64 "com.sun.star.text.DocumentIndex",
65 "com.sun.star.text.TableIndex",
66 "com.sun.star.text.ObjectIndex",
67 "com.sun.star.text.Bibliography",
68 "com.sun.star.text.UserIndex",
69 "com.sun.star.text.IllustrationsIndex"
70};
71
73{
81};
82
84{
93};
94
95
97 sal_Int32 nElement)
98 : SvXMLImportContext(rImport)
99 , eIndexType(TEXT_INDEX_UNKNOWN)
100 , bValid(false)
101{
103 {
104 if (SvXMLUnitConverter::convertEnum(eIndexType, SvXMLImport::getNameFromToken(nElement), aIndexTypeMap))
105 {
106 // check for array index:
107 OSL_ENSURE(unsigned(eIndexType) < (SAL_N_ELEMENTS(aIndexServiceMap)), "index out of range");
108 OSL_ENSURE(SAL_N_ELEMENTS(aIndexServiceMap) ==
110 "service and source element maps must be same size");
111 bValid = true;
112 }
113 }
114}
115
117{
118}
119
121 sal_Int32 nElement,
122 const css::uno::Reference< css::xml::sax::XFastAttributeList >& xAttrList )
123{
124 if (!bValid)
125 return;
126
127 // find text:style-name attribute and set section style
128 // find text:protected and set value
129 // find text:name and set value (if not empty)
130 bool bProtected = false;
131 OUString sIndexName;
132 OUString sXmlId;
133 XMLPropStyleContext* pStyle(nullptr);
134 for( auto& aIter : sax_fastparser::castToFastAttributeList(xAttrList) )
135 {
136 switch(aIter.getToken())
137 {
139 {
140 pStyle = GetImport().GetTextImport()->FindSectionStyle(
141 aIter.toString());
142 break;
143 }
145 {
146 bool bTmp(false);
147 if (::sax::Converter::convertBool(bTmp, aIter.toView()))
148 {
149 bProtected = bTmp;
150 }
151 break;
152 }
154 {
155 sIndexName = aIter.toString();
156 break;
157 }
158 case XML_ELEMENT(XML, XML_ID):
159 {
160 sXmlId = aIter.toString();
161 break;
162 }
163 default:
164 XMLOFF_WARN_UNKNOWN("xmloff", aIter);
165 }
166 }
167
168 // create table of content (via MultiServiceFactory)
169 Reference<XMultiServiceFactory> xFactory(GetImport().GetModel(),
170 UNO_QUERY);
171 if( xFactory.is() )
172 {
173 Reference<XInterface> xIfc =
174 xFactory->createInstance(
175 OUString::createFromAscii(aIndexServiceMap[eIndexType]));
176 if( xIfc.is() )
177 {
178 // get Property set
179 Reference<XPropertySet> xPropSet(xIfc, UNO_QUERY);
180 xTOCPropertySet = xPropSet;
181
182 // insert section
183 // a) insert section
184 // The inserted index consists of an empty paragraph
185 // only, as well as an empty paragraph *after* the index
186 // b) insert marker after index, and put Cursor inside of the
187 // index
188
189 // preliminaries
190#ifndef DBG_UTIL
191 static constexpr OUStringLiteral sMarker(u" ");
192#else
193 static constexpr OUStringLiteral sMarker(u"Y");
194#endif
196 GetImport().GetTextImport();
197
198 // a) insert index
199 Reference<XTextContent> xTextContent(xIfc, UNO_QUERY);
200 try
201 {
202 GetImport().GetTextImport()->InsertTextContent(
203 xTextContent);
204 }
205 catch(const IllegalArgumentException& e)
206 {
207 // illegal argument? Then we can't accept indices here!
208 Sequence<OUString> aSeq { SvXMLImport::getNameFromToken(nElement) };
209 GetImport().SetError(
211 aSeq, e.Message, nullptr );
212
213 // set bValid to false, and return prematurely
214 bValid = false;
215 return;
216 }
217
218 // xml:id for RDF metadata
219 GetImport().SetXmlId(xIfc, sXmlId);
220
221 // b) insert marker and move cursor
222 rImport->InsertString(sMarker);
223 rImport->GetCursor()->goLeft(2, false);
224 }
225 }
226
227 // finally, check for redlines that should start at
228 // the section start node
229 if( bValid )
230 GetImport().GetTextImport()->RedlineAdjustStartNodeCursor();
231
232 if (pStyle != nullptr)
233 {
235 }
236
237 xTOCPropertySet->setPropertyValue( "IsProtected", Any(bProtected) );
238
239 if (!sIndexName.isEmpty())
240 {
241 xTOCPropertySet->setPropertyValue( "Name", Any(sIndexName) );
242 }
243
244}
245
247{
248 // complete import of index by removing the markers (if the index
249 // was actually inserted, that is)
250 if( !bValid )
251 return;
252
253 // preliminaries
254 rtl::Reference<XMLTextImportHelper> rHelper= GetImport().GetTextImport();
255
256 // get rid of last paragraph (unless it's the only paragraph)
257 rHelper->GetCursor()->goRight(1, false);
258 if( xBodyContextRef.is() && xBodyContextRef->HasContent() )
259 {
260 rHelper->GetCursor()->goLeft(1, true);
261 rHelper->GetText()->insertString(rHelper->GetCursorAsRange(),
262 "", true);
263 }
264
265 // and delete second marker
266 rHelper->GetCursor()->goRight(1, true);
267 rHelper->GetText()->insertString(rHelper->GetCursorAsRange(),
268 "", true);
269
270 // check for Redlines on our end node
271 GetImport().GetTextImport()->RedlineAdjustStartNodeCursor();
272}
273
274css::uno::Reference< css::xml::sax::XFastContextHandler > XMLIndexTOCContext::createFastChildContext(
275 sal_Int32 nElement,
276 const css::uno::Reference< css::xml::sax::XFastAttributeList >& )
277{
278 SvXMLImportContextRef xContext;
279
280 // not valid -> ignore
281 if (!bValid)
282 return nullptr;
283
284 if (nElement == XML_ELEMENT(TEXT, XML_INDEX_BODY) )
285 {
287 xContext = xNewBodyContext;
288 if ( !xBodyContextRef.is() || !xBodyContextRef->HasContent() )
289 {
290 xBodyContextRef = xNewBodyContext;
291 }
292 }
293 else if (nElement == XML_ELEMENT(TEXT, aIndexSourceElementMap[eIndexType]))
294 {
295 // instantiate source context for the appropriate index type
296 switch (eIndexType)
297 {
298 case TEXT_INDEX_TOC:
299 xContext = new XMLIndexTOCSourceContext(
301 break;
302
304 xContext = new XMLIndexObjectSourceContext(
306 break;
307
311 break;
312
313 case TEXT_INDEX_USER:
314 xContext = new XMLIndexUserSourceContext(
316 break;
317
321 break;
322
323 case TEXT_INDEX_TABLE:
324 xContext = new XMLIndexTableSourceContext(
326 break;
327
331 break;
332
333 default:
334 OSL_FAIL("index type not implemented");
335 break;
336 }
337 }
338 // else: ignore
339
340 return xContext;
341}
342
343/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
SvXMLEnumMapEntry< IndexTypeEnum > const aIndexTypeMap[]
static const char * aIndexServiceMap[]
const XMLTokenEnum aIndexSourceElementMap[]
@ TEXT_INDEX_TABLE
@ TEXT_INDEX_ALPHABETICAL
@ TEXT_INDEX_USER
@ TEXT_INDEX_BIBLIOGRAPHY
@ TEXT_INDEX_TOC
@ TEXT_INDEX_OBJECT
@ TEXT_INDEX_UNKNOWN
@ TEXT_INDEX_ILLUSTRATION
This class deliberately does not support XWeak, to improve performance when loading large documents.
Definition: xmlictxt.hxx:48
SvXMLImport & GetImport()
Definition: xmlictxt.hxx:60
static bool convertEnum(EnumT &rEnum, std::u16string_view rValue, const SvXMLEnumMapEntry< EnumT > *pMap)
convert string to enum using given enum map, if the enum is not found in the map, this method will re...
Definition: xmluconv.hxx:145
Import alphabetical (keyword) index source element.
Import index body.
Import illustration index source element;.
Import object index source element.
virtual void SAL_CALL startFastElement(sal_Int32 nElement, const css::uno::Reference< css::xml::sax::XFastAttributeList > &xAttrList) override
enum IndexTypeEnum eIndexType
virtual void SAL_CALL endFastElement(sal_Int32 nElement) override
endFastElement is called before a context will be destructed, but after an elements context has been ...
virtual css::uno::Reference< css::xml::sax::XFastContextHandler > SAL_CALL createFastChildContext(sal_Int32 nElement, const css::uno::Reference< css::xml::sax::XFastAttributeList > &xAttrList) override
virtual ~XMLIndexTOCContext() override
css::uno::Reference< css::beans::XPropertySet > xTOCPropertySet
XPropertySet of the index.
rtl::Reference< XMLIndexBodyContext > xBodyContextRef
XMLIndexTOCContext(SvXMLImport &rImport, sal_Int32 nElement)
Import table of context source element.
Import table index source element.
Import user defined index source element.
virtual void FillPropertySet(const css::uno::Reference< css::beans::XPropertySet > &rPropSet)
Definition: prstylei.cxx:222
static bool convertBool(bool &rBool, std::u16string_view rString)
float u
Reference< XSingleServiceFactory > xFactory
Sequence< sal_Int8 > aSeq
#define SAL_N_ELEMENTS(arr)
FastAttributeList & castToFastAttributeList(const css::uno::Reference< css::xml::sax::XFastAttributeList > &xAttrList)
Handling of tokens in XML:
XMLTokenEnum
The enumeration of all XML tokens.
Definition: xmltoken.hxx:50
@ XML_ILLUSTRATION_INDEX
Definition: xmltoken.hxx:1073
@ XML_TABLE_INDEX_SOURCE
Definition: xmltoken.hxx:1924
@ XML_ILLUSTRATION_INDEX_SOURCE
Definition: xmltoken.hxx:1075
@ XML_BIBLIOGRAPHY_SOURCE
Definition: xmltoken.hxx:332
@ XML_OBJECT_INDEX_SOURCE
Definition: xmltoken.hxx:1427
@ XML_ALPHABETICAL_INDEX
Definition: xmltoken.hxx:236
@ XML_TABLE_OF_CONTENT_SOURCE
Definition: xmltoken.hxx:1928
@ XML_ALPHABETICAL_INDEX_SOURCE
Definition: xmltoken.hxx:242
TEXT
#define XMLERROR_NO_INDEX_ALLOWED_HERE
Definition: xmlerror.hxx:54
#define XMLERROR_FLAG_ERROR
Definition: xmlerror.hxx:36
#define XMLOFF_WARN_UNKNOWN(area, rIter)
Definition: xmlictxt.hxx:114
#define XML_ELEMENT(prefix, name)
Definition: xmlimp.hxx:97
constexpr bool IsTokenInNamespace(sal_Int32 nToken, sal_uInt16 nNamespacePrefix)
Definition: xmlimp.hxx:104
constexpr sal_uInt16 XML_NAMESPACE_TEXT