1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
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/xmlnamespace.hxx>
41 #include <xmloff/xmltoken.hxx>
42 #include <xmloff/prstylei.hxx>
43 #include <xmloff/xmlerror.hxx>
44 #include <xmloff/xmluconv.hxx>
45 #include <xmloff/xmlement.hxx>
46 #include <rtl/ustring.hxx>
47 #include <osl/diagnose.h>
50 using namespace ::com::sun::star::uno
;
51 using namespace ::com::sun::star::text
;
52 using namespace ::xmloff::token
;
54 using ::com::sun::star::uno::Reference
;
55 using ::com::sun::star::lang::XMultiServiceFactory
;
56 using ::com::sun::star::lang::IllegalArgumentException
;
59 constexpr OUString aIndexServiceMap
[]
61 u
"com.sun.star.text.ContentIndex"_ustr
,
62 u
"com.sun.star.text.DocumentIndex"_ustr
,
63 u
"com.sun.star.text.TableIndex"_ustr
,
64 u
"com.sun.star.text.ObjectIndex"_ustr
,
65 u
"com.sun.star.text.Bibliography"_ustr
,
66 u
"com.sun.star.text.UserIndex"_ustr
,
67 u
"com.sun.star.text.IllustrationsIndex"_ustr
70 const XMLTokenEnum aIndexSourceElementMap
[] =
72 XML_TABLE_OF_CONTENT_SOURCE
,
73 XML_ALPHABETICAL_INDEX_SOURCE
,
74 XML_TABLE_INDEX_SOURCE
,
75 XML_OBJECT_INDEX_SOURCE
,
76 XML_BIBLIOGRAPHY_SOURCE
,
77 XML_USER_INDEX_SOURCE
,
78 XML_ILLUSTRATION_INDEX_SOURCE
81 SvXMLEnumMapEntry
<IndexTypeEnum
> const aIndexTypeMap
[] =
83 { XML_TABLE_OF_CONTENT
, TEXT_INDEX_TOC
},
84 { XML_ALPHABETICAL_INDEX
, TEXT_INDEX_ALPHABETICAL
},
85 { XML_TABLE_INDEX
, TEXT_INDEX_TABLE
},
86 { XML_OBJECT_INDEX
, TEXT_INDEX_OBJECT
},
87 { XML_BIBLIOGRAPHY
, TEXT_INDEX_BIBLIOGRAPHY
},
88 { XML_USER_INDEX
, TEXT_INDEX_USER
},
89 { XML_ILLUSTRATION_INDEX
, TEXT_INDEX_ILLUSTRATION
},
90 { XML_TOKEN_INVALID
, IndexTypeEnum(0) }
94 XMLIndexTOCContext::XMLIndexTOCContext(SvXMLImport
& rImport
,
96 : SvXMLImportContext(rImport
)
97 , eIndexType(TEXT_INDEX_UNKNOWN
)
100 if (IsTokenInNamespace(nElement
, XML_NAMESPACE_TEXT
))
102 if (SvXMLUnitConverter::convertEnum(eIndexType
, SvXMLImport::getNameFromToken(nElement
), aIndexTypeMap
))
104 // check for array index:
105 OSL_ENSURE(unsigned(eIndexType
) < (SAL_N_ELEMENTS(aIndexServiceMap
)), "index out of range");
106 OSL_ENSURE(SAL_N_ELEMENTS(aIndexServiceMap
) ==
107 SAL_N_ELEMENTS(aIndexSourceElementMap
),
108 "service and source element maps must be same size");
114 XMLIndexTOCContext::~XMLIndexTOCContext()
118 void XMLIndexTOCContext::startFastElement(
120 const css::uno::Reference
< css::xml::sax::XFastAttributeList
>& xAttrList
)
125 // find text:style-name attribute and set section style
126 // find text:protected and set value
127 // find text:name and set value (if not empty)
128 bool bProtected
= false;
131 XMLPropStyleContext
* pStyle(nullptr);
132 for( auto& aIter
: sax_fastparser::castToFastAttributeList(xAttrList
) )
134 switch(aIter
.getToken())
136 case XML_ELEMENT(TEXT
, XML_STYLE_NAME
):
138 pStyle
= GetImport().GetTextImport()->FindSectionStyle(
142 case XML_ELEMENT(TEXT
, XML_PROTECTED
):
145 if (::sax::Converter::convertBool(bTmp
, aIter
.toView()))
151 case XML_ELEMENT(TEXT
, XML_NAME
):
153 sIndexName
= aIter
.toString();
156 case XML_ELEMENT(XML
, XML_ID
):
158 sXmlId
= aIter
.toString();
162 XMLOFF_WARN_UNKNOWN("xmloff", aIter
);
166 // create table of content (via MultiServiceFactory)
167 Reference
<XMultiServiceFactory
> xFactory(GetImport().GetModel(),
171 Reference
<XInterface
> xIfc
= xFactory
->createInstance(aIndexServiceMap
[eIndexType
]);
175 xTOCPropertySet
.set(xIfc
, UNO_QUERY
);
179 // The inserted index consists of an empty paragraph
180 // only, as well as an empty paragraph *after* the index
181 // b) insert marker after index, and put Cursor inside of the
186 static constexpr OUStringLiteral
sMarker(u
" ");
188 static constexpr OUStringLiteral
sMarker(u
"Y");
190 rtl::Reference
<XMLTextImportHelper
> rImport
=
191 GetImport().GetTextImport();
194 Reference
<XTextContent
> xTextContent(xIfc
, UNO_QUERY
);
197 GetImport().GetTextImport()->InsertTextContent(
200 catch(const IllegalArgumentException
& e
)
202 // illegal argument? Then we can't accept indices here!
203 Sequence
<OUString
> aSeq
{ SvXMLImport::getNameFromToken(nElement
) };
204 GetImport().SetError(
205 XMLERROR_FLAG_ERROR
| XMLERROR_NO_INDEX_ALLOWED_HERE
,
206 aSeq
, e
.Message
, nullptr );
208 // set bValid to false, and return prematurely
213 // xml:id for RDF metadata
214 GetImport().SetXmlId(xIfc
, sXmlId
);
216 // b) insert marker and move cursor
217 rImport
->InsertString(sMarker
);
218 rImport
->GetCursor()->goLeft(2, false);
222 // finally, check for redlines that should start at
223 // the section start node
225 GetImport().GetTextImport()->RedlineAdjustStartNodeCursor();
227 if (pStyle
!= nullptr)
229 pStyle
->FillPropertySet( xTOCPropertySet
);
232 xTOCPropertySet
->setPropertyValue( u
"IsProtected"_ustr
, Any(bProtected
) );
234 if (!sIndexName
.isEmpty())
236 xTOCPropertySet
->setPropertyValue( u
"Name"_ustr
, Any(sIndexName
) );
241 void XMLIndexTOCContext::endFastElement(sal_Int32
)
243 // complete import of index by removing the markers (if the index
244 // was actually inserted, that is)
249 rtl::Reference
<XMLTextImportHelper
> rHelper
= GetImport().GetTextImport();
251 // get rid of last paragraph (unless it's the only paragraph)
252 rHelper
->GetCursor()->goRight(1, false);
253 if( xBodyContextRef
.is() && xBodyContextRef
->HasContent() )
255 rHelper
->GetCursor()->goLeft(1, true);
256 rHelper
->GetText()->insertString(rHelper
->GetCursorAsRange(),
260 // and delete second marker
261 rHelper
->GetCursor()->goRight(1, true);
262 rHelper
->GetText()->insertString(rHelper
->GetCursorAsRange(),
265 // check for Redlines on our end node
266 GetImport().GetTextImport()->RedlineAdjustStartNodeCursor();
269 css::uno::Reference
< css::xml::sax::XFastContextHandler
> XMLIndexTOCContext::createFastChildContext(
271 const css::uno::Reference
< css::xml::sax::XFastAttributeList
>& )
273 SvXMLImportContextRef xContext
;
275 // not valid -> ignore
279 if (nElement
== XML_ELEMENT(TEXT
, XML_INDEX_BODY
) )
281 rtl::Reference
<XMLIndexBodyContext
> xNewBodyContext
= new XMLIndexBodyContext(GetImport());
282 xContext
= xNewBodyContext
;
283 if ( !xBodyContextRef
.is() || !xBodyContextRef
->HasContent() )
285 xBodyContextRef
= std::move(xNewBodyContext
);
288 else if (nElement
== XML_ELEMENT(TEXT
, aIndexSourceElementMap
[eIndexType
]))
290 // instantiate source context for the appropriate index type
294 xContext
= new XMLIndexTOCSourceContext(
295 GetImport(), xTOCPropertySet
);
298 case TEXT_INDEX_OBJECT
:
299 xContext
= new XMLIndexObjectSourceContext(
300 GetImport(), xTOCPropertySet
);
303 case TEXT_INDEX_ALPHABETICAL
:
304 xContext
= new XMLIndexAlphabeticalSourceContext(
305 GetImport(), xTOCPropertySet
);
308 case TEXT_INDEX_USER
:
309 xContext
= new XMLIndexUserSourceContext(
310 GetImport(), xTOCPropertySet
);
313 case TEXT_INDEX_BIBLIOGRAPHY
:
314 xContext
= new XMLIndexBibliographySourceContext(
315 GetImport(), xTOCPropertySet
);
318 case TEXT_INDEX_TABLE
:
319 xContext
= new XMLIndexTableSourceContext(
320 GetImport(), xTOCPropertySet
);
323 case TEXT_INDEX_ILLUSTRATION
:
324 xContext
= new XMLIndexIllustrationSourceContext(
325 GetImport(), xTOCPropertySet
);
329 OSL_FAIL("index type not implemented");
338 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */