1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*************************************************************************
4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
6 * Copyright 2000, 2010 Oracle and/or its affiliates.
8 * OpenOffice.org - a multi-platform office productivity suite
10 * This file is part of OpenOffice.org.
12 * OpenOffice.org is free software: you can redistribute it and/or modify
13 * it under the terms of the GNU Lesser General Public License version 3
14 * only, as published by the Free Software Foundation.
16 * OpenOffice.org is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU Lesser General Public License version 3 for more details
20 * (a copy is included in the LICENSE file that accompanied this code).
22 * You should have received a copy of the GNU Lesser General Public License
23 * version 3 along with OpenOffice.org. If not, see
24 * <http://www.openoffice.org/license.html>
25 * for a copy of the LGPLv3 License.
27 ************************************************************************/
31 #include "XMLIndexTOCContext.hxx"
32 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
33 #include <com/sun/star/lang/IllegalArgumentException.hpp>
34 #include <com/sun/star/uno/XInterface.hpp>
35 #include <com/sun/star/text/XTextContent.hpp>
36 #include <com/sun/star/text/XTextSection.hpp>
37 #include <com/sun/star/text/XRelativeTextContentInsert.hpp>
38 #include <com/sun/star/beans/XPropertySet.hpp>
39 #include <sax/tools/converter.hxx>
40 #include "XMLIndexTOCSourceContext.hxx"
41 #include "XMLIndexObjectSourceContext.hxx"
42 #include "XMLIndexAlphabeticalSourceContext.hxx"
43 #include "XMLIndexUserSourceContext.hxx"
44 #include "XMLIndexBibliographySourceContext.hxx"
45 #include "XMLIndexTableSourceContext.hxx"
46 #include "XMLIndexIllustrationSourceContext.hxx"
47 #include "XMLIndexBodyContext.hxx"
48 #include <xmloff/xmlictxt.hxx>
49 #include <xmloff/xmlimp.hxx>
50 #include <xmloff/txtimp.hxx>
51 #include <xmloff/nmspmap.hxx>
52 #include "xmloff/xmlnmspe.hxx"
53 #include <xmloff/xmltoken.hxx>
54 #include <xmloff/prstylei.hxx>
55 #include "xmloff/xmlerror.hxx"
56 #include <xmloff/xmluconv.hxx>
57 #include <rtl/ustring.hxx>
60 using namespace ::com::sun::star::uno
;
61 using namespace ::com::sun::star::text
;
62 using namespace ::xmloff::token
;
64 using ::rtl::OUString
;
65 using ::com::sun::star::beans::XPropertySet
;
66 using ::com::sun::star::uno::Reference
;
67 using ::com::sun::star::xml::sax::XAttributeList
;
68 using ::com::sun::star::lang::XMultiServiceFactory
;
69 using ::com::sun::star::lang::IllegalArgumentException
;
72 TYPEINIT1(XMLIndexTOCContext
, SvXMLImportContext
);
74 static const sal_Char
* aIndexServiceMap
[] =
76 "com.sun.star.text.ContentIndex",
77 "com.sun.star.text.DocumentIndex",
78 "com.sun.star.text.TableIndex",
79 "com.sun.star.text.ObjectIndex",
80 "com.sun.star.text.Bibliography",
81 "com.sun.star.text.UserIndex",
82 "com.sun.star.text.IllustrationsIndex"
85 static const XMLTokenEnum aIndexSourceElementMap
[] =
87 XML_TABLE_OF_CONTENT_SOURCE
,
88 XML_ALPHABETICAL_INDEX_SOURCE
,
89 XML_TABLE_INDEX_SOURCE
,
90 XML_OBJECT_INDEX_SOURCE
,
91 XML_BIBLIOGRAPHY_SOURCE
,
92 XML_USER_INDEX_SOURCE
,
93 XML_ILLUSTRATION_INDEX_SOURCE
96 SvXMLEnumMapEntry
const aIndexTypeMap
[] =
98 { XML_TABLE_OF_CONTENT
, TEXT_INDEX_TOC
},
99 { XML_ALPHABETICAL_INDEX
, TEXT_INDEX_ALPHABETICAL
},
100 { XML_TABLE_INDEX
, TEXT_INDEX_TABLE
},
101 { XML_OBJECT_INDEX
, TEXT_INDEX_OBJECT
},
102 { XML_BIBLIOGRAPHY
, TEXT_INDEX_BIBLIOGRAPHY
},
103 { XML_USER_INDEX
, TEXT_INDEX_USER
},
104 { XML_ILLUSTRATION_INDEX
, TEXT_INDEX_ILLUSTRATION
},
105 { XML_TOKEN_INVALID
, 0 }
109 XMLIndexTOCContext::XMLIndexTOCContext(
110 SvXMLImport
& rImport
,
112 const OUString
& rLocalName
)
113 : SvXMLImportContext(rImport
, nPrfx
, rLocalName
)
114 , sTitle(RTL_CONSTASCII_USTRINGPARAM("Title"))
115 , sIsProtected(RTL_CONSTASCII_USTRINGPARAM("IsProtected"))
116 , sName(RTL_CONSTASCII_USTRINGPARAM("Name"))
119 if (XML_NAMESPACE_TEXT
== nPrfx
)
122 if (SvXMLUnitConverter::convertEnum(nTmp
, rLocalName
, aIndexTypeMap
))
124 // check for array index:
125 OSL_ENSURE(nTmp
< (SAL_N_ELEMENTS(aIndexServiceMap
)), "index out of range");
126 OSL_ENSURE(SAL_N_ELEMENTS(aIndexServiceMap
) ==
127 SAL_N_ELEMENTS(aIndexSourceElementMap
),
128 "service and source element maps must be same size");
130 eIndexType
= static_cast<IndexTypeEnum
>(nTmp
);
136 XMLIndexTOCContext::~XMLIndexTOCContext()
140 void XMLIndexTOCContext::StartElement(
141 const Reference
<XAttributeList
> & xAttrList
)
145 // find text:style-name attribute and set section style
146 // find text:protected and set value
147 // find text:name and set value (if not empty)
148 sal_Int16 nCount
= xAttrList
->getLength();
149 sal_Bool bProtected
= sal_False
;
152 XMLPropStyleContext
* pStyle(NULL
);
153 for(sal_Int16 nAttr
= 0; nAttr
< nCount
; nAttr
++)
156 sal_uInt16 nPrefix
= GetImport().GetNamespaceMap().
157 GetKeyByAttrName( xAttrList
->getNameByIndex(nAttr
),
159 if ( XML_NAMESPACE_TEXT
== nPrefix
)
161 if ( IsXMLToken( sLocalName
, XML_STYLE_NAME
) )
163 pStyle
= GetImport().GetTextImport()->FindSectionStyle(
164 xAttrList
->getValueByIndex(nAttr
));
166 else if ( IsXMLToken( sLocalName
, XML_PROTECTED
) )
169 if (::sax::Converter::convertBool(
170 bTmp
, xAttrList
->getValueByIndex(nAttr
)))
175 else if ( IsXMLToken( sLocalName
, XML_NAME
) )
177 sIndexName
= xAttrList
->getValueByIndex(nAttr
);
180 else if ( XML_NAMESPACE_XML
== nPrefix
)
182 if ( IsXMLToken( sLocalName
, XML_ID
) )
184 sXmlId
= xAttrList
->getValueByIndex(nAttr
);
189 // create table of content (via MultiServiceFactory)
190 Reference
<XMultiServiceFactory
> xFactory(GetImport().GetModel(),
194 Reference
<XInterface
> xIfc
=
195 xFactory
->createInstance(
196 OUString::createFromAscii(aIndexServiceMap
[eIndexType
]));
200 Reference
<XPropertySet
> xPropSet(xIfc
, UNO_QUERY
);
201 xTOCPropertySet
= xPropSet
;
205 // The inserted index consists of an empty paragraph
206 // only, as well as an empty paragraph *after* the index
207 // b) insert marker after index, and put Cursor inside of the
212 OUString
sMarker(RTL_CONSTASCII_USTRINGPARAM(" "));
214 OUString
sMarker(RTL_CONSTASCII_USTRINGPARAM("Y"));
216 UniReference
<XMLTextImportHelper
> rImport
=
217 GetImport().GetTextImport();
220 Reference
<XTextContent
> xTextContent(xIfc
, UNO_QUERY
);
223 GetImport().GetTextImport()->InsertTextContent(
226 catch(const IllegalArgumentException
& e
)
228 // illegal argument? Then we can't accept indices here!
229 Sequence
<OUString
> aSeq(1);
230 aSeq
[0] = GetLocalName();
231 GetImport().SetError(
232 XMLERROR_FLAG_ERROR
| XMLERROR_NO_INDEX_ALLOWED_HERE
,
233 aSeq
, e
.Message
, NULL
);
235 // set bValid to false, and return prematurely
240 // xml:id for RDF metadata
241 GetImport().SetXmlId(xIfc
, sXmlId
);
243 // b) insert marker and move cursor
244 rImport
->InsertString(sMarker
);
245 rImport
->GetCursor()->goLeft(2, sal_False
);
249 // finally, check for redlines that should start at
250 // the section start node
252 GetImport().GetTextImport()->
253 RedlineAdjustStartNodeCursor(sal_True
);
257 pStyle
->FillPropertySet( xTOCPropertySet
);
261 aAny
.setValue( &bProtected
, ::getBooleanCppuType() );
262 xTOCPropertySet
->setPropertyValue( sIsProtected
, aAny
);
264 if (!sIndexName
.isEmpty())
267 xTOCPropertySet
->setPropertyValue( sName
, aAny
);
272 void XMLIndexTOCContext::EndElement()
274 // complete import of index by removing the markers (if the index
275 // was actually inserted, that is)
280 UniReference
<XMLTextImportHelper
> rHelper
= GetImport().GetTextImport();
282 // get rid of last paragraph (unless it's the only paragraph)
283 rHelper
->GetCursor()->goRight(1, sal_False
);
284 if( xBodyContextRef
.Is() &&
285 ((XMLIndexBodyContext
*)&xBodyContextRef
)->HasContent() )
287 rHelper
->GetCursor()->goLeft(1, sal_True
);
288 rHelper
->GetText()->insertString(rHelper
->GetCursorAsRange(),
292 // and delete second marker
293 rHelper
->GetCursor()->goRight(1, sal_True
);
294 rHelper
->GetText()->insertString(rHelper
->GetCursorAsRange(),
297 // check for Redlines on our end node
298 GetImport().GetTextImport()->RedlineAdjustStartNodeCursor(sal_False
);
302 SvXMLImportContext
* XMLIndexTOCContext::CreateChildContext(
304 const OUString
& rLocalName
,
305 const Reference
<XAttributeList
> & xAttrList
)
307 SvXMLImportContext
* pContext
= NULL
;
311 if (XML_NAMESPACE_TEXT
== nPrefix
)
313 if ( IsXMLToken( rLocalName
, XML_INDEX_BODY
) )
315 pContext
= new XMLIndexBodyContext(GetImport(), nPrefix
,
317 if ( !xBodyContextRef
.Is() ||
318 !((XMLIndexBodyContext
*)&xBodyContextRef
)->HasContent() )
320 xBodyContextRef
= pContext
;
323 else if (IsXMLToken(rLocalName
, aIndexSourceElementMap
[eIndexType
]))
325 // instantiate source context for the appropriate index type
329 pContext
= new XMLIndexTOCSourceContext(
330 GetImport(), nPrefix
, rLocalName
, xTOCPropertySet
);
333 case TEXT_INDEX_OBJECT
:
334 pContext
= new XMLIndexObjectSourceContext(
335 GetImport(), nPrefix
, rLocalName
, xTOCPropertySet
);
338 case TEXT_INDEX_ALPHABETICAL
:
339 pContext
= new XMLIndexAlphabeticalSourceContext(
340 GetImport(), nPrefix
, rLocalName
, xTOCPropertySet
);
343 case TEXT_INDEX_USER
:
344 pContext
= new XMLIndexUserSourceContext(
345 GetImport(), nPrefix
, rLocalName
, xTOCPropertySet
);
348 case TEXT_INDEX_BIBLIOGRAPHY
:
349 pContext
= new XMLIndexBibliographySourceContext(
350 GetImport(), nPrefix
, rLocalName
, xTOCPropertySet
);
353 case TEXT_INDEX_TABLE
:
354 pContext
= new XMLIndexTableSourceContext(
355 GetImport(), nPrefix
, rLocalName
, xTOCPropertySet
);
358 case TEXT_INDEX_ILLUSTRATION
:
359 pContext
= new XMLIndexIllustrationSourceContext(
360 GetImport(), nPrefix
, rLocalName
, xTOCPropertySet
);
364 OSL_FAIL("index type not implemented");
370 // else: no text: namespace -> ignore
372 // else: not valid -> ignore
375 if (pContext
== NULL
)
377 pContext
= SvXMLImportContext::CreateChildContext(nPrefix
, rLocalName
,
384 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */