1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: XMLIndexTOCContext.cxx,v $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_xmloff.hxx"
35 #include "XMLIndexTOCContext.hxx"
36 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
37 #include <com/sun/star/lang/IllegalArgumentException.hpp>
38 #include <com/sun/star/uno/XInterface.hpp>
39 #include <com/sun/star/text/XTextContent.hpp>
40 #include <com/sun/star/text/XTextSection.hpp>
41 #include <com/sun/star/text/XRelativeTextContentInsert.hpp>
42 #include <com/sun/star/beans/XPropertySet.hpp>
43 #include "XMLIndexTOCSourceContext.hxx"
44 #include "XMLIndexObjectSourceContext.hxx"
45 #include "XMLIndexAlphabeticalSourceContext.hxx"
46 #include "XMLIndexUserSourceContext.hxx"
47 #include "XMLIndexBibliographySourceContext.hxx"
48 #include "XMLIndexTableSourceContext.hxx"
49 #include "XMLIndexIllustrationSourceContext.hxx"
50 #include "XMLIndexBodyContext.hxx"
51 #include <xmloff/xmlictxt.hxx>
52 #include <xmloff/xmlimp.hxx>
53 #include <xmloff/txtimp.hxx>
54 #include <xmloff/nmspmap.hxx>
55 #include "xmlnmspe.hxx"
56 #include "xmlkywd.hxx"
57 #include <xmloff/xmltoken.hxx>
58 #include <xmloff/prstylei.hxx>
59 #include "xmlerror.hxx"
60 #include <xmloff/xmluconv.hxx>
61 #include <tools/debug.hxx>
62 #include <rtl/ustring.hxx>
63 #include <tools/debug.hxx>
66 using namespace ::com::sun::star::uno
;
67 using namespace ::com::sun::star::text
;
68 using namespace ::xmloff::token
;
70 using ::rtl::OUString
;
71 using ::com::sun::star::beans::XPropertySet
;
72 using ::com::sun::star::uno::Reference
;
73 using ::com::sun::star::xml::sax::XAttributeList
;
74 using ::com::sun::star::lang::XMultiServiceFactory
;
75 using ::com::sun::star::lang::IllegalArgumentException
;
78 TYPEINIT1(XMLIndexTOCContext
, SvXMLImportContext
);
80 static const sal_Char
* aIndexServiceMap
[] =
82 "com.sun.star.text.ContentIndex",
83 "com.sun.star.text.DocumentIndex",
84 "com.sun.star.text.TableIndex",
85 "com.sun.star.text.ObjectIndex",
86 "com.sun.star.text.Bibliography",
87 "com.sun.star.text.UserIndex",
88 "com.sun.star.text.IllustrationsIndex"
91 static const sal_Char
* aIndexSourceElementMap
[] =
93 sXML_table_of_content_source
,
94 sXML_alphabetical_index_source
,
95 sXML_table_index_source
,
96 sXML_object_index_source
,
97 sXML_bibliography_source
,
98 sXML_user_index_source
,
99 sXML_illustration_index_source
102 SvXMLEnumMapEntry __READONLY_DATA aIndexTypeMap
[] =
104 { XML_TABLE_OF_CONTENT
, TEXT_INDEX_TOC
},
105 { XML_ALPHABETICAL_INDEX
, TEXT_INDEX_ALPHABETICAL
},
106 { XML_TABLE_INDEX
, TEXT_INDEX_TABLE
},
107 { XML_OBJECT_INDEX
, TEXT_INDEX_OBJECT
},
108 { XML_BIBLIOGRAPHY
, TEXT_INDEX_BIBLIOGRAPHY
},
109 { XML_USER_INDEX
, TEXT_INDEX_USER
},
110 { XML_ILLUSTRATION_INDEX
, TEXT_INDEX_ILLUSTRATION
},
111 { XML_TOKEN_INVALID
, 0 }
115 XMLIndexTOCContext::XMLIndexTOCContext(
116 SvXMLImport
& rImport
,
118 const OUString
& rLocalName
)
119 : SvXMLImportContext(rImport
, nPrfx
, rLocalName
)
120 , sTitle(RTL_CONSTASCII_USTRINGPARAM("Title"))
121 , sIsProtected(RTL_CONSTASCII_USTRINGPARAM("IsProtected"))
122 , sName(RTL_CONSTASCII_USTRINGPARAM("Name"))
123 , pSourceElementName(NULL
)
126 if (XML_NAMESPACE_TEXT
== nPrfx
)
129 if (SvXMLUnitConverter::convertEnum(nTmp
, rLocalName
, aIndexTypeMap
))
131 // check for array index:
132 DBG_ASSERT(nTmp
< (sizeof(aIndexServiceMap
)/sizeof(sal_Char
*)), "index out of range");
133 DBG_ASSERT(sizeof(aIndexServiceMap
) ==
134 sizeof(aIndexSourceElementMap
),
135 "service and source element maps must be same size");
137 eIndexType
= (enum IndexTypeEnum
)nTmp
;
138 pSourceElementName
= aIndexSourceElementMap
[eIndexType
];
144 XMLIndexTOCContext::~XMLIndexTOCContext()
148 void XMLIndexTOCContext::StartElement(
149 const Reference
<XAttributeList
> & xAttrList
)
153 // find text:style-name attribute and set section style
154 // find text:protected and set value
155 // find text:name and set value (if not empty)
156 sal_Int16 nCount
= xAttrList
->getLength();
157 sal_Bool bProtected
= sal_False
;
160 XMLPropStyleContext
* pStyle(NULL
);
161 for(sal_Int16 nAttr
= 0; nAttr
< nCount
; nAttr
++)
164 sal_uInt16 nPrefix
= GetImport().GetNamespaceMap().
165 GetKeyByAttrName( xAttrList
->getNameByIndex(nAttr
),
167 if ( XML_NAMESPACE_TEXT
== nPrefix
)
169 if ( IsXMLToken( sLocalName
, XML_STYLE_NAME
) )
171 pStyle
= GetImport().GetTextImport()->FindSectionStyle(
172 xAttrList
->getValueByIndex(nAttr
));
174 else if ( IsXMLToken( sLocalName
, XML_PROTECTED
) )
177 if ( SvXMLUnitConverter::convertBool(
178 bTmp
, xAttrList
->getValueByIndex(nAttr
) ) )
183 else if ( IsXMLToken( sLocalName
, XML_NAME
) )
185 sIndexName
= xAttrList
->getValueByIndex(nAttr
);
188 else if ( XML_NAMESPACE_XML
== nPrefix
)
190 if ( IsXMLToken( sLocalName
, XML_ID
) )
192 sXmlId
= xAttrList
->getValueByIndex(nAttr
);
197 // create table of content (via MultiServiceFactory)
198 Reference
<XMultiServiceFactory
> xFactory(GetImport().GetModel(),
202 Reference
<XInterface
> xIfc
=
203 xFactory
->createInstance(
204 OUString::createFromAscii(aIndexServiceMap
[eIndexType
]));
208 // xml:id for RDF metadata
209 GetImport().SetXmlId(xIfc
, sXmlId
);
212 Reference
<XPropertySet
> xPropSet(xIfc
, UNO_QUERY
);
213 xTOCPropertySet
= xPropSet
;
217 // The inserted index consists of an empty paragraph
218 // only, as well as an empty paragraph *after* the index
219 // b) insert marker after index, and put Cursor inside of the
224 OUString
sMarker(RTL_CONSTASCII_USTRINGPARAM(" "));
226 OUString
sMarker(RTL_CONSTASCII_USTRINGPARAM("Y"));
228 UniReference
<XMLTextImportHelper
> rImport
=
229 GetImport().GetTextImport();
232 Reference
<XTextContent
> xTextContent(xIfc
, UNO_QUERY
);
235 GetImport().GetTextImport()->InsertTextContent(
238 catch( IllegalArgumentException e
)
240 // illegal argument? Then we can't accept indices here!
241 Sequence
<OUString
> aSeq(1);
242 aSeq
[0] = GetLocalName();
243 GetImport().SetError(
244 XMLERROR_FLAG_ERROR
| XMLERROR_NO_INDEX_ALLOWED_HERE
,
245 aSeq
, e
.Message
, NULL
);
247 // set bValid to false, and return prematurely
252 // b) insert marker and move cursor
253 rImport
->InsertString(sMarker
);
254 rImport
->GetCursor()->goLeft(2, sal_False
);
258 // finally, check for redlines that should start at
259 // the section start node
261 GetImport().GetTextImport()->
262 RedlineAdjustStartNodeCursor(sal_True
);
266 pStyle
->FillPropertySet( xTOCPropertySet
);
270 aAny
.setValue( &bProtected
, ::getBooleanCppuType() );
271 xTOCPropertySet
->setPropertyValue( sIsProtected
, aAny
);
273 if (sIndexName
.getLength() > 0)
276 xTOCPropertySet
->setPropertyValue( sName
, aAny
);
281 void XMLIndexTOCContext::EndElement()
283 // complete import of index by removing the markers (if the index
284 // was actually inserted, that is)
289 UniReference
<XMLTextImportHelper
> rHelper
= GetImport().GetTextImport();
291 // get rid of last paragraph (unless it's the only paragraph)
292 rHelper
->GetCursor()->goRight(1, sal_False
);
293 if( xBodyContextRef
.Is() &&
294 ((XMLIndexBodyContext
*)&xBodyContextRef
)->HasContent() )
296 rHelper
->GetCursor()->goLeft(1, sal_True
);
297 rHelper
->GetText()->insertString(rHelper
->GetCursorAsRange(),
301 // and delete second marker
302 rHelper
->GetCursor()->goRight(1, sal_True
);
303 rHelper
->GetText()->insertString(rHelper
->GetCursorAsRange(),
306 // check for Redlines on our end node
307 GetImport().GetTextImport()->RedlineAdjustStartNodeCursor(sal_False
);
311 SvXMLImportContext
* XMLIndexTOCContext::CreateChildContext(
313 const OUString
& rLocalName
,
314 const Reference
<XAttributeList
> & xAttrList
)
316 SvXMLImportContext
* pContext
= NULL
;
320 if (XML_NAMESPACE_TEXT
== nPrefix
)
322 if ( IsXMLToken( rLocalName
, XML_INDEX_BODY
) )
324 pContext
= new XMLIndexBodyContext(GetImport(), nPrefix
,
326 if ( !xBodyContextRef
.Is() ||
327 !((XMLIndexBodyContext
*)&xBodyContextRef
)->HasContent() )
329 xBodyContextRef
= pContext
;
332 else if (0 == rLocalName
.compareToAscii(pSourceElementName
))
334 // instantiate source context for the appropriate index type
338 pContext
= new XMLIndexTOCSourceContext(
339 GetImport(), nPrefix
, rLocalName
, xTOCPropertySet
);
342 case TEXT_INDEX_OBJECT
:
343 pContext
= new XMLIndexObjectSourceContext(
344 GetImport(), nPrefix
, rLocalName
, xTOCPropertySet
);
347 case TEXT_INDEX_ALPHABETICAL
:
348 pContext
= new XMLIndexAlphabeticalSourceContext(
349 GetImport(), nPrefix
, rLocalName
, xTOCPropertySet
);
352 case TEXT_INDEX_USER
:
353 pContext
= new XMLIndexUserSourceContext(
354 GetImport(), nPrefix
, rLocalName
, xTOCPropertySet
);
357 case TEXT_INDEX_BIBLIOGRAPHY
:
358 pContext
= new XMLIndexBibliographySourceContext(
359 GetImport(), nPrefix
, rLocalName
, xTOCPropertySet
);
362 case TEXT_INDEX_TABLE
:
363 pContext
= new XMLIndexTableSourceContext(
364 GetImport(), nPrefix
, rLocalName
, xTOCPropertySet
);
367 case TEXT_INDEX_ILLUSTRATION
:
368 pContext
= new XMLIndexIllustrationSourceContext(
369 GetImport(), nPrefix
, rLocalName
, xTOCPropertySet
);
373 DBG_ERROR("index type not implemented");
379 // else: no text: namespace -> ignore
381 // else: not valid -> ignore
384 if (pContext
== NULL
)
386 pContext
= SvXMLImportContext::CreateChildContext(nPrefix
, rLocalName
,