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::xml::sax::XAttributeList;
58using ::com::sun::star::lang::XMultiServiceFactory;
59using ::com::sun::star::lang::IllegalArgumentException;
60
61
62static const char* aIndexServiceMap[] =
63{
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"
71};
72
74{
82};
83
85{
94};
95
96
98 sal_Int32 nElement)
99 : SvXMLImportContext(rImport)
100 , eIndexType(TEXT_INDEX_UNKNOWN)
101 , bValid(false)
102{
104 {
105 if (SvXMLUnitConverter::convertEnum(eIndexType, SvXMLImport::getNameFromToken(nElement), aIndexTypeMap))
106 {
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) ==
111 "service and source element maps must be same size");
112 bValid = true;
113 }
114 }
115}
116
118{
119}
120
122 sal_Int32 nElement,
123 const css::uno::Reference< css::xml::sax::XFastAttributeList >& xAttrList )
124{
125 if (!bValid)
126 return;
127
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) )
136 {
137 switch(aIter.getToken())
138 {
140 {
141 pStyle = GetImport().GetTextImport()->FindSectionStyle(
142 aIter.toString());
143 break;
144 }
146 {
147 bool bTmp(false);
148 if (::sax::Converter::convertBool(bTmp, aIter.toView()))
149 {
150 bProtected = bTmp;
151 }
152 break;
153 }
155 {
156 sIndexName = aIter.toString();
157 break;
158 }
159 case XML_ELEMENT(XML, XML_ID):
160 {
161 sXmlId = aIter.toString();
162 break;
163 }
164 default:
165 XMLOFF_WARN_UNKNOWN("xmloff", aIter);
166 }
167 }
168
169 // create table of content (via MultiServiceFactory)
170 Reference<XMultiServiceFactory> xFactory(GetImport().GetModel(),
171 UNO_QUERY);
172 if( xFactory.is() )
173 {
174 Reference<XInterface> xIfc =
175 xFactory->createInstance(
176 OUString::createFromAscii(aIndexServiceMap[eIndexType]));
177 if( xIfc.is() )
178 {
179 // get Property set
180 Reference<XPropertySet> xPropSet(xIfc, UNO_QUERY);
181 xTOCPropertySet = xPropSet;
182
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
189
190 // preliminaries
191#ifndef DBG_UTIL
192 OUString const sMarker(" ");
193#else
194 OUString const sMarker("Y");
195#endif
197 GetImport().GetTextImport();
198
199 // a) insert index
200 Reference<XTextContent> xTextContent(xIfc, UNO_QUERY);
201 try
202 {
203 GetImport().GetTextImport()->InsertTextContent(
204 xTextContent);
205 }
206 catch(const IllegalArgumentException& e)
207 {
208 // illegal argument? Then we can't accept indices here!
209 Sequence<OUString> aSeq { SvXMLImport::getNameFromToken(nElement) };
210 GetImport().SetError(
212 aSeq, e.Message, nullptr );
213
214 // set bValid to false, and return prematurely
215 bValid = false;
216 return;
217 }
218
219 // xml:id for RDF metadata
220 GetImport().SetXmlId(xIfc, sXmlId);
221
222 // b) insert marker and move cursor
223 rImport->InsertString(sMarker);
224 rImport->GetCursor()->goLeft(2, false);
225 }
226 }
227
228 // finally, check for redlines that should start at
229 // the section start node
230 if( bValid )
231 GetImport().GetTextImport()->RedlineAdjustStartNodeCursor();
232
233 if (pStyle != nullptr)
234 {
236 }
237
238 xTOCPropertySet->setPropertyValue( "IsProtected", Any(bProtected) );
239
240 if (!sIndexName.isEmpty())
241 {
242 xTOCPropertySet->setPropertyValue( "Name", Any(sIndexName) );
243 }
244
245}
246
248{
249 // complete import of index by removing the markers (if the index
250 // was actually inserted, that is)
251 if( !bValid )
252 return;
253
254 // preliminaries
255 rtl::Reference<XMLTextImportHelper> rHelper= GetImport().GetTextImport();
256
257 // get rid of last paragraph (unless it's the only paragraph)
258 rHelper->GetCursor()->goRight(1, false);
259 if( xBodyContextRef.is() && xBodyContextRef->HasContent() )
260 {
261 rHelper->GetCursor()->goLeft(1, true);
262 rHelper->GetText()->insertString(rHelper->GetCursorAsRange(),
263 "", true);
264 }
265
266 // and delete second marker
267 rHelper->GetCursor()->goRight(1, true);
268 rHelper->GetText()->insertString(rHelper->GetCursorAsRange(),
269 "", true);
270
271 // check for Redlines on our end node
272 GetImport().GetTextImport()->RedlineAdjustStartNodeCursor();
273}
274
275css::uno::Reference< css::xml::sax::XFastContextHandler > XMLIndexTOCContext::createFastChildContext(
276 sal_Int32 nElement,
277 const css::uno::Reference< css::xml::sax::XFastAttributeList >& )
278{
279 SvXMLImportContextRef xContext;
280
281 // not valid -> ignore
282 if (!bValid)
283 return nullptr;
284
285 if (nElement == XML_ELEMENT(TEXT, XML_INDEX_BODY) )
286 {
288 xContext = xNewBodyContext;
289 if ( !xBodyContextRef.is() || !xBodyContextRef->HasContent() )
290 {
291 xBodyContextRef = xNewBodyContext;
292 }
293 }
294 else if (nElement == XML_ELEMENT(TEXT, aIndexSourceElementMap[eIndexType]))
295 {
296 // instantiate source context for the appropriate index type
297 switch (eIndexType)
298 {
299 case TEXT_INDEX_TOC:
300 xContext = new XMLIndexTOCSourceContext(
302 break;
303
305 xContext = new XMLIndexObjectSourceContext(
307 break;
308
312 break;
313
314 case TEXT_INDEX_USER:
315 xContext = new XMLIndexUserSourceContext(
317 break;
318
322 break;
323
324 case TEXT_INDEX_TABLE:
325 xContext = new XMLIndexTableSourceContext(
327 break;
328
332 break;
333
334 default:
335 OSL_FAIL("index type not implemented");
336 break;
337 }
338 }
339 // else: ignore
340
341 return xContext;
342}
343
344/* 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)
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:1071
@ XML_TABLE_INDEX_SOURCE
Definition: xmltoken.hxx:1919
@ XML_ILLUSTRATION_INDEX_SOURCE
Definition: xmltoken.hxx:1073
@ XML_BIBLIOGRAPHY_SOURCE
Definition: xmltoken.hxx:330
@ XML_OBJECT_INDEX_SOURCE
Definition: xmltoken.hxx:1423
@ XML_ALPHABETICAL_INDEX
Definition: xmltoken.hxx:236
@ XML_TABLE_OF_CONTENT_SOURCE
Definition: xmltoken.hxx:1923
@ 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