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/lang/XMultiServiceFactory.hpp>
22 #include <com/sun/star/lang/IllegalArgumentException.hpp>
23 #include <com/sun/star/uno/XInterface.hpp>
24 #include <com/sun/star/text/XTextContent.hpp>
25 #include <com/sun/star/text/XTextSection.hpp>
26 #include <com/sun/star/text/XRelativeTextContentInsert.hpp>
27 #include <com/sun/star/beans/XPropertySet.hpp>
28 #include <sax/tools/converter.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/nmspmap.hxx>
41 #include <xmloff/xmlnmspe.hxx>
42 #include <xmloff/xmltoken.hxx>
43 #include <xmloff/prstylei.hxx>
44 #include <xmloff/xmlerror.hxx>
45 #include <xmloff/xmluconv.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::beans::XPropertySet
;
55 using ::com::sun::star::uno::Reference
;
56 using ::com::sun::star::xml::sax::XAttributeList
;
57 using ::com::sun::star::lang::XMultiServiceFactory
;
58 using ::com::sun::star::lang::IllegalArgumentException
;
61 TYPEINIT1(XMLIndexTOCContext
, SvXMLImportContext
);
63 static const sal_Char
* aIndexServiceMap
[] =
65 "com.sun.star.text.ContentIndex",
66 "com.sun.star.text.DocumentIndex",
67 "com.sun.star.text.TableIndex",
68 "com.sun.star.text.ObjectIndex",
69 "com.sun.star.text.Bibliography",
70 "com.sun.star.text.UserIndex",
71 "com.sun.star.text.IllustrationsIndex"
74 static const XMLTokenEnum aIndexSourceElementMap
[] =
76 XML_TABLE_OF_CONTENT_SOURCE
,
77 XML_ALPHABETICAL_INDEX_SOURCE
,
78 XML_TABLE_INDEX_SOURCE
,
79 XML_OBJECT_INDEX_SOURCE
,
80 XML_BIBLIOGRAPHY_SOURCE
,
81 XML_USER_INDEX_SOURCE
,
82 XML_ILLUSTRATION_INDEX_SOURCE
85 SvXMLEnumMapEntry
const aIndexTypeMap
[] =
87 { XML_TABLE_OF_CONTENT
, TEXT_INDEX_TOC
},
88 { XML_ALPHABETICAL_INDEX
, TEXT_INDEX_ALPHABETICAL
},
89 { XML_TABLE_INDEX
, TEXT_INDEX_TABLE
},
90 { XML_OBJECT_INDEX
, TEXT_INDEX_OBJECT
},
91 { XML_BIBLIOGRAPHY
, TEXT_INDEX_BIBLIOGRAPHY
},
92 { XML_USER_INDEX
, TEXT_INDEX_USER
},
93 { XML_ILLUSTRATION_INDEX
, TEXT_INDEX_ILLUSTRATION
},
94 { XML_TOKEN_INVALID
, 0 }
98 XMLIndexTOCContext::XMLIndexTOCContext(SvXMLImport
& rImport
,
99 sal_uInt16 nPrfx
, const OUString
& rLocalName
)
100 : SvXMLImportContext(rImport
, nPrfx
, rLocalName
)
101 , sIsProtected("IsProtected")
103 , eIndexType(TEXT_INDEX_UNKNOWN
)
106 if (XML_NAMESPACE_TEXT
== nPrfx
)
109 if (SvXMLUnitConverter::convertEnum(nTmp
, rLocalName
, aIndexTypeMap
))
111 // check for array index:
112 OSL_ENSURE(nTmp
< (SAL_N_ELEMENTS(aIndexServiceMap
)), "index out of range");
113 OSL_ENSURE(SAL_N_ELEMENTS(aIndexServiceMap
) ==
114 SAL_N_ELEMENTS(aIndexSourceElementMap
),
115 "service and source element maps must be same size");
117 eIndexType
= static_cast<IndexTypeEnum
>(nTmp
);
123 XMLIndexTOCContext::~XMLIndexTOCContext()
127 void XMLIndexTOCContext::StartElement(
128 const Reference
<XAttributeList
> & xAttrList
)
132 // find text:style-name attribute and set section style
133 // find text:protected and set value
134 // find text:name and set value (if not empty)
135 sal_Int16 nCount
= xAttrList
->getLength();
136 sal_Bool bProtected
= sal_False
;
139 XMLPropStyleContext
* pStyle(NULL
);
140 for(sal_Int16 nAttr
= 0; nAttr
< nCount
; nAttr
++)
143 sal_uInt16 nPrefix
= GetImport().GetNamespaceMap().
144 GetKeyByAttrName( xAttrList
->getNameByIndex(nAttr
),
146 if ( XML_NAMESPACE_TEXT
== nPrefix
)
148 if ( IsXMLToken( sLocalName
, XML_STYLE_NAME
) )
150 pStyle
= GetImport().GetTextImport()->FindSectionStyle(
151 xAttrList
->getValueByIndex(nAttr
));
153 else if ( IsXMLToken( sLocalName
, XML_PROTECTED
) )
156 if (::sax::Converter::convertBool(
157 bTmp
, xAttrList
->getValueByIndex(nAttr
)))
162 else if ( IsXMLToken( sLocalName
, XML_NAME
) )
164 sIndexName
= xAttrList
->getValueByIndex(nAttr
);
167 else if ( XML_NAMESPACE_XML
== nPrefix
)
169 if ( IsXMLToken( sLocalName
, XML_ID
) )
171 sXmlId
= xAttrList
->getValueByIndex(nAttr
);
176 // create table of content (via MultiServiceFactory)
177 Reference
<XMultiServiceFactory
> xFactory(GetImport().GetModel(),
181 Reference
<XInterface
> xIfc
=
182 xFactory
->createInstance(
183 OUString::createFromAscii(aIndexServiceMap
[eIndexType
]));
187 Reference
<XPropertySet
> xPropSet(xIfc
, UNO_QUERY
);
188 xTOCPropertySet
= xPropSet
;
192 // The inserted index consists of an empty paragraph
193 // only, as well as an empty paragraph *after* the index
194 // b) insert marker after index, and put Cursor inside of the
199 OUString
sMarker(" ");
201 OUString
sMarker("Y");
203 rtl::Reference
<XMLTextImportHelper
> rImport
=
204 GetImport().GetTextImport();
207 Reference
<XTextContent
> xTextContent(xIfc
, UNO_QUERY
);
210 GetImport().GetTextImport()->InsertTextContent(
213 catch(const IllegalArgumentException
& e
)
215 // illegal argument? Then we can't accept indices here!
216 Sequence
<OUString
> aSeq(1);
217 aSeq
[0] = GetLocalName();
218 GetImport().SetError(
219 XMLERROR_FLAG_ERROR
| XMLERROR_NO_INDEX_ALLOWED_HERE
,
220 aSeq
, e
.Message
, NULL
);
222 // set bValid to false, and return prematurely
227 // xml:id for RDF metadata
228 GetImport().SetXmlId(xIfc
, sXmlId
);
230 // b) insert marker and move cursor
231 rImport
->InsertString(sMarker
);
232 rImport
->GetCursor()->goLeft(2, sal_False
);
236 // finally, check for redlines that should start at
237 // the section start node
239 GetImport().GetTextImport()->RedlineAdjustStartNodeCursor(true);
243 pStyle
->FillPropertySet( xTOCPropertySet
);
247 aAny
.setValue( &bProtected
, cppu::UnoType
<bool>::get() );
248 xTOCPropertySet
->setPropertyValue( sIsProtected
, aAny
);
250 if (!sIndexName
.isEmpty())
253 xTOCPropertySet
->setPropertyValue( sName
, aAny
);
258 void XMLIndexTOCContext::EndElement()
260 // complete import of index by removing the markers (if the index
261 // was actually inserted, that is)
266 rtl::Reference
<XMLTextImportHelper
> rHelper
= GetImport().GetTextImport();
268 // get rid of last paragraph (unless it's the only paragraph)
269 rHelper
->GetCursor()->goRight(1, sal_False
);
270 if( xBodyContextRef
.Is() &&
271 static_cast<XMLIndexBodyContext
*>(&xBodyContextRef
)->HasContent() )
273 rHelper
->GetCursor()->goLeft(1, sal_True
);
274 rHelper
->GetText()->insertString(rHelper
->GetCursorAsRange(),
278 // and delete second marker
279 rHelper
->GetCursor()->goRight(1, sal_True
);
280 rHelper
->GetText()->insertString(rHelper
->GetCursorAsRange(),
283 // check for Redlines on our end node
284 GetImport().GetTextImport()->RedlineAdjustStartNodeCursor(false);
288 SvXMLImportContext
* XMLIndexTOCContext::CreateChildContext(
290 const OUString
& rLocalName
,
291 const Reference
<XAttributeList
> & xAttrList
)
293 SvXMLImportContext
* pContext
= NULL
;
297 if (XML_NAMESPACE_TEXT
== nPrefix
)
299 if ( IsXMLToken( rLocalName
, XML_INDEX_BODY
) )
301 pContext
= new XMLIndexBodyContext(GetImport(), nPrefix
,
303 if ( !xBodyContextRef
.Is() ||
304 !static_cast<XMLIndexBodyContext
*>(&xBodyContextRef
)->HasContent() )
306 xBodyContextRef
= pContext
;
309 else if (IsXMLToken(rLocalName
, aIndexSourceElementMap
[eIndexType
]))
311 // instantiate source context for the appropriate index type
315 pContext
= new XMLIndexTOCSourceContext(
316 GetImport(), nPrefix
, rLocalName
, xTOCPropertySet
);
319 case TEXT_INDEX_OBJECT
:
320 pContext
= new XMLIndexObjectSourceContext(
321 GetImport(), nPrefix
, rLocalName
, xTOCPropertySet
);
324 case TEXT_INDEX_ALPHABETICAL
:
325 pContext
= new XMLIndexAlphabeticalSourceContext(
326 GetImport(), nPrefix
, rLocalName
, xTOCPropertySet
);
329 case TEXT_INDEX_USER
:
330 pContext
= new XMLIndexUserSourceContext(
331 GetImport(), nPrefix
, rLocalName
, xTOCPropertySet
);
334 case TEXT_INDEX_BIBLIOGRAPHY
:
335 pContext
= new XMLIndexBibliographySourceContext(
336 GetImport(), nPrefix
, rLocalName
, xTOCPropertySet
);
339 case TEXT_INDEX_TABLE
:
340 pContext
= new XMLIndexTableSourceContext(
341 GetImport(), nPrefix
, rLocalName
, xTOCPropertySet
);
344 case TEXT_INDEX_ILLUSTRATION
:
345 pContext
= new XMLIndexIllustrationSourceContext(
346 GetImport(), nPrefix
, rLocalName
, xTOCPropertySet
);
350 OSL_FAIL("index type not implemented");
356 // else: no text: namespace -> ignore
358 // else: not valid -> ignore
361 if (pContext
== NULL
)
363 pContext
= SvXMLImportContext::CreateChildContext(nPrefix
, rLocalName
,
370 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */