Branch data Line data Source code
1 : : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : : /*************************************************************************
3 : : *
4 : : * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 : : *
6 : : * Copyright 2000, 2010 Oracle and/or its affiliates.
7 : : *
8 : : * OpenOffice.org - a multi-platform office productivity suite
9 : : *
10 : : * This file is part of OpenOffice.org.
11 : : *
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.
15 : : *
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).
21 : : *
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.
26 : : *
27 : : ************************************************************************/
28 : :
29 : : #include "XMLIndexTOCContext.hxx"
30 : : #include <com/sun/star/lang/XMultiServiceFactory.hpp>
31 : : #include <com/sun/star/lang/IllegalArgumentException.hpp>
32 : : #include <com/sun/star/uno/XInterface.hpp>
33 : : #include <com/sun/star/text/XTextContent.hpp>
34 : : #include <com/sun/star/text/XTextSection.hpp>
35 : : #include <com/sun/star/text/XRelativeTextContentInsert.hpp>
36 : : #include <com/sun/star/beans/XPropertySet.hpp>
37 : : #include <sax/tools/converter.hxx>
38 : : #include "XMLIndexTOCSourceContext.hxx"
39 : : #include "XMLIndexObjectSourceContext.hxx"
40 : : #include "XMLIndexAlphabeticalSourceContext.hxx"
41 : : #include "XMLIndexUserSourceContext.hxx"
42 : : #include "XMLIndexBibliographySourceContext.hxx"
43 : : #include "XMLIndexTableSourceContext.hxx"
44 : : #include "XMLIndexIllustrationSourceContext.hxx"
45 : : #include "XMLIndexBodyContext.hxx"
46 : : #include <xmloff/xmlictxt.hxx>
47 : : #include <xmloff/xmlimp.hxx>
48 : : #include <xmloff/txtimp.hxx>
49 : : #include <xmloff/nmspmap.hxx>
50 : : #include "xmloff/xmlnmspe.hxx"
51 : : #include <xmloff/xmltoken.hxx>
52 : : #include <xmloff/prstylei.hxx>
53 : : #include "xmloff/xmlerror.hxx"
54 : : #include <xmloff/xmluconv.hxx>
55 : : #include <rtl/ustring.hxx>
56 : :
57 : :
58 : : using namespace ::com::sun::star::uno;
59 : : using namespace ::com::sun::star::text;
60 : : using namespace ::xmloff::token;
61 : :
62 : : using ::rtl::OUString;
63 : : using ::com::sun::star::beans::XPropertySet;
64 : : using ::com::sun::star::uno::Reference;
65 : : using ::com::sun::star::xml::sax::XAttributeList;
66 : : using ::com::sun::star::lang::XMultiServiceFactory;
67 : : using ::com::sun::star::lang::IllegalArgumentException;
68 : :
69 : :
70 [ # # ][ # # ]: 0 : TYPEINIT1(XMLIndexTOCContext, SvXMLImportContext);
71 : :
72 : : static const sal_Char* aIndexServiceMap[] =
73 : : {
74 : : "com.sun.star.text.ContentIndex",
75 : : "com.sun.star.text.DocumentIndex",
76 : : "com.sun.star.text.TableIndex",
77 : : "com.sun.star.text.ObjectIndex",
78 : : "com.sun.star.text.Bibliography",
79 : : "com.sun.star.text.UserIndex",
80 : : "com.sun.star.text.IllustrationsIndex"
81 : : };
82 : :
83 : : static const XMLTokenEnum aIndexSourceElementMap[] =
84 : : {
85 : : XML_TABLE_OF_CONTENT_SOURCE,
86 : : XML_ALPHABETICAL_INDEX_SOURCE,
87 : : XML_TABLE_INDEX_SOURCE,
88 : : XML_OBJECT_INDEX_SOURCE,
89 : : XML_BIBLIOGRAPHY_SOURCE,
90 : : XML_USER_INDEX_SOURCE,
91 : : XML_ILLUSTRATION_INDEX_SOURCE
92 : : };
93 : :
94 : : SvXMLEnumMapEntry const aIndexTypeMap[] =
95 : : {
96 : : { XML_TABLE_OF_CONTENT, TEXT_INDEX_TOC },
97 : : { XML_ALPHABETICAL_INDEX, TEXT_INDEX_ALPHABETICAL },
98 : : { XML_TABLE_INDEX, TEXT_INDEX_TABLE },
99 : : { XML_OBJECT_INDEX, TEXT_INDEX_OBJECT },
100 : : { XML_BIBLIOGRAPHY, TEXT_INDEX_BIBLIOGRAPHY },
101 : : { XML_USER_INDEX, TEXT_INDEX_USER },
102 : : { XML_ILLUSTRATION_INDEX, TEXT_INDEX_ILLUSTRATION },
103 : : { XML_TOKEN_INVALID, 0 }
104 : : };
105 : :
106 : :
107 : 28 : XMLIndexTOCContext::XMLIndexTOCContext(
108 : : SvXMLImport& rImport,
109 : : sal_uInt16 nPrfx,
110 : : const OUString& rLocalName )
111 : : : SvXMLImportContext(rImport, nPrfx, rLocalName)
112 : : , sTitle(RTL_CONSTASCII_USTRINGPARAM("Title"))
113 : : , sIsProtected(RTL_CONSTASCII_USTRINGPARAM("IsProtected"))
114 : : , sName(RTL_CONSTASCII_USTRINGPARAM("Name"))
115 [ + - ][ + - ]: 28 : , bValid(sal_False)
[ + - ]
116 : : {
117 [ + - ]: 28 : if (XML_NAMESPACE_TEXT == nPrfx)
118 : : {
119 : : sal_uInt16 nTmp;
120 [ + - ][ + - ]: 28 : if (SvXMLUnitConverter::convertEnum(nTmp, rLocalName, aIndexTypeMap))
121 : : {
122 : : // check for array index:
123 : : OSL_ENSURE(nTmp < (SAL_N_ELEMENTS(aIndexServiceMap)), "index out of range");
124 : : OSL_ENSURE(SAL_N_ELEMENTS(aIndexServiceMap) ==
125 : : SAL_N_ELEMENTS(aIndexSourceElementMap),
126 : : "service and source element maps must be same size");
127 : :
128 : 28 : eIndexType = static_cast<IndexTypeEnum>(nTmp);
129 : 28 : bValid = sal_True;
130 : : }
131 : : }
132 : 28 : }
133 : :
134 [ + - ]: 28 : XMLIndexTOCContext::~XMLIndexTOCContext()
135 : : {
136 [ - + ]: 56 : }
137 : :
138 : 28 : void XMLIndexTOCContext::StartElement(
139 : : const Reference<XAttributeList> & xAttrList)
140 : : {
141 [ + - ]: 28 : if (bValid)
142 : : {
143 : : // find text:style-name attribute and set section style
144 : : // find text:protected and set value
145 : : // find text:name and set value (if not empty)
146 [ + - ][ + - ]: 28 : sal_Int16 nCount = xAttrList->getLength();
147 : 28 : sal_Bool bProtected = sal_False;
148 : 28 : OUString sIndexName;
149 : 28 : OUString sXmlId;
150 : 28 : XMLPropStyleContext* pStyle(NULL);
151 [ + + ]: 140 : for(sal_Int16 nAttr = 0; nAttr < nCount; nAttr++)
152 : : {
153 : 112 : OUString sLocalName;
154 : 112 : sal_uInt16 nPrefix = GetImport().GetNamespaceMap().
155 [ + - ]: 112 : GetKeyByAttrName( xAttrList->getNameByIndex(nAttr),
156 [ + - + - ]: 224 : &sLocalName );
157 [ + + ]: 112 : if ( XML_NAMESPACE_TEXT == nPrefix)
158 : : {
159 [ + - ][ + + ]: 84 : if ( IsXMLToken( sLocalName, XML_STYLE_NAME ) )
160 : : {
161 : 28 : pStyle = GetImport().GetTextImport()->FindSectionStyle(
162 [ + - ]: 56 : xAttrList->getValueByIndex(nAttr));
[ + - + - ]
[ + - ][ + - ]
[ + - ]
163 : : }
164 [ + - ][ + + ]: 56 : else if ( IsXMLToken( sLocalName, XML_PROTECTED ) )
165 : : {
166 : 28 : bool bTmp(false);
167 [ + - + - ]: 56 : if (::sax::Converter::convertBool(
168 [ + - ][ + - ]: 56 : bTmp, xAttrList->getValueByIndex(nAttr)))
169 : : {
170 : 28 : bProtected = bTmp;
171 : : }
172 : : }
173 [ + - ][ + - ]: 28 : else if ( IsXMLToken( sLocalName, XML_NAME ) )
174 : : {
175 [ + - ][ + - ]: 28 : sIndexName = xAttrList->getValueByIndex(nAttr);
176 : : }
177 : : }
178 [ + - ]: 28 : else if ( XML_NAMESPACE_XML == nPrefix)
179 : : {
180 [ + - ][ + - ]: 28 : if ( IsXMLToken( sLocalName, XML_ID ) )
181 : : {
182 [ + - ][ + - ]: 28 : sXmlId = xAttrList->getValueByIndex(nAttr);
183 : : }
184 : : }
185 : 112 : }
186 : :
187 : : // create table of content (via MultiServiceFactory)
188 : 28 : Reference<XMultiServiceFactory> xFactory(GetImport().GetModel(),
189 [ + - ]: 28 : UNO_QUERY);
190 [ + - ]: 28 : if( xFactory.is() )
191 : : {
192 : : Reference<XInterface> xIfc =
193 [ + - ]: 28 : xFactory->createInstance(
194 [ + - ]: 28 : OUString::createFromAscii(aIndexServiceMap[eIndexType]));
195 [ + - ]: 28 : if( xIfc.is() )
196 : : {
197 : : // get Property set
198 [ + - ]: 28 : Reference<XPropertySet> xPropSet(xIfc, UNO_QUERY);
199 [ + - ]: 28 : xTOCPropertySet = xPropSet;
200 : :
201 : : // insert section
202 : : // a) insert section
203 : : // The inserted index consists of an empty paragraph
204 : : // only, as well as an empty paragraph *after* the index
205 : : // b) insert marker after index, and put Cursor inside of the
206 : : // index
207 : :
208 : : // preliminaries
209 : : #ifndef DBG_UTIL
210 [ + - ]: 28 : OUString sMarker(RTL_CONSTASCII_USTRINGPARAM(" "));
211 : : #else
212 : : OUString sMarker(RTL_CONSTASCII_USTRINGPARAM("Y"));
213 : : #endif
214 : : UniReference<XMLTextImportHelper> rImport =
215 [ + - ]: 28 : GetImport().GetTextImport();
216 : :
217 : : // a) insert index
218 [ + - ]: 28 : Reference<XTextContent> xTextContent(xIfc, UNO_QUERY);
219 : : try
220 : : {
221 : 28 : GetImport().GetTextImport()->InsertTextContent(
222 [ + - ][ + - ]: 28 : xTextContent);
[ + - ][ + - ]
223 : : }
224 [ # # # # ]: 0 : catch(const IllegalArgumentException& e)
225 : : {
226 : : // illegal argument? Then we can't accept indices here!
227 [ # # ]: 0 : Sequence<OUString> aSeq(1);
228 [ # # ]: 0 : aSeq[0] = GetLocalName();
229 : 0 : GetImport().SetError(
230 : : XMLERROR_FLAG_ERROR | XMLERROR_NO_INDEX_ALLOWED_HERE,
231 [ # # # # ]: 0 : aSeq, e.Message, NULL );
232 : :
233 : : // set bValid to false, and return prematurely
234 : 0 : bValid = false;
235 [ # # ]: 28 : return;
236 : : }
237 : :
238 : : // xml:id for RDF metadata
239 [ + - ]: 28 : GetImport().SetXmlId(xIfc, sXmlId);
240 : :
241 : : // b) insert marker and move cursor
242 [ + - ][ + - ]: 28 : rImport->InsertString(sMarker);
243 [ + - ][ + - ]: 28 : rImport->GetCursor()->goLeft(2, sal_False);
[ + - ][ + - ]
[ - + ][ + - ]
[ - + ][ - + ]
[ + - ]
244 [ + - ]: 28 : }
245 : : }
246 : :
247 : : // finally, check for redlines that should start at
248 : : // the section start node
249 [ + - ]: 28 : if( bValid )
250 [ + - ][ + - ]: 56 : GetImport().GetTextImport()->
[ + - ]
251 [ + - ]: 28 : RedlineAdjustStartNodeCursor(sal_True);
252 : :
253 [ + - ]: 28 : if (pStyle != NULL)
254 : : {
255 [ + - ]: 28 : pStyle->FillPropertySet( xTOCPropertySet );
256 : : }
257 : :
258 : 28 : Any aAny;
259 [ + - ]: 28 : aAny.setValue( &bProtected, ::getBooleanCppuType() );
260 [ + - ][ + - ]: 28 : xTOCPropertySet->setPropertyValue( sIsProtected, aAny );
261 : :
262 [ + - ]: 28 : if (!sIndexName.isEmpty())
263 : : {
264 [ + - ]: 28 : aAny <<= sIndexName;
265 [ + - ][ + - ]: 28 : xTOCPropertySet->setPropertyValue( sName, aAny );
266 [ - + ][ - + ]: 28 : }
[ + - ]
267 : : }
268 : : }
269 : :
270 : 28 : void XMLIndexTOCContext::EndElement()
271 : : {
272 : : // complete import of index by removing the markers (if the index
273 : : // was actually inserted, that is)
274 [ + - ]: 28 : if( bValid )
275 : : {
276 : : // preliminaries
277 : 28 : OUString sEmpty;
278 [ + - ]: 28 : UniReference<XMLTextImportHelper> rHelper= GetImport().GetTextImport();
279 : :
280 : : // get rid of last paragraph (unless it's the only paragraph)
281 [ + - ][ + - ]: 28 : rHelper->GetCursor()->goRight(1, sal_False);
[ + - ][ + - ]
282 [ + - + - ]: 56 : if( xBodyContextRef.Is() &&
[ + - ]
283 : 28 : ((XMLIndexBodyContext*)&xBodyContextRef)->HasContent() )
284 : : {
285 [ + - ][ + - ]: 28 : rHelper->GetCursor()->goLeft(1, sal_True);
[ + - ][ + - ]
286 [ + - ][ + - ]: 28 : rHelper->GetText()->insertString(rHelper->GetCursorAsRange(),
[ + - ][ + - ]
[ + - ]
287 [ + - ]: 28 : sEmpty, sal_True);
288 : : }
289 : :
290 : : // and delete second marker
291 [ + - ][ + - ]: 28 : rHelper->GetCursor()->goRight(1, sal_True);
[ + - ][ + - ]
292 [ + - ][ + - ]: 28 : rHelper->GetText()->insertString(rHelper->GetCursorAsRange(),
[ + - ][ + - ]
[ + - ]
293 [ + - ]: 28 : sEmpty, sal_True);
294 : :
295 : : // check for Redlines on our end node
296 [ + - ][ + - ]: 28 : GetImport().GetTextImport()->RedlineAdjustStartNodeCursor(sal_False);
[ + - ][ + - ]
[ + - ]
297 : : }
298 : 28 : }
299 : :
300 : 56 : SvXMLImportContext* XMLIndexTOCContext::CreateChildContext(
301 : : sal_uInt16 nPrefix,
302 : : const OUString& rLocalName,
303 : : const Reference<XAttributeList> & xAttrList )
304 : : {
305 : 56 : SvXMLImportContext* pContext = NULL;
306 : :
307 [ + - ]: 56 : if (bValid)
308 : : {
309 [ + - ]: 56 : if (XML_NAMESPACE_TEXT == nPrefix)
310 : : {
311 [ + + ]: 56 : if ( IsXMLToken( rLocalName, XML_INDEX_BODY ) )
312 : : {
313 : 28 : pContext = new XMLIndexBodyContext(GetImport(), nPrefix,
314 [ + - ]: 28 : rLocalName);
315 [ - + # # ]: 28 : if ( !xBodyContextRef.Is() ||
[ + - ]
316 : 0 : !((XMLIndexBodyContext*)&xBodyContextRef)->HasContent() )
317 : : {
318 : 28 : xBodyContextRef = pContext;
319 : : }
320 : : }
321 [ + - ]: 28 : else if (IsXMLToken(rLocalName, aIndexSourceElementMap[eIndexType]))
322 : : {
323 : : // instantiate source context for the appropriate index type
324 [ + + + + : 28 : switch (eIndexType)
+ + + - ]
325 : : {
326 : : case TEXT_INDEX_TOC:
327 : : pContext = new XMLIndexTOCSourceContext(
328 [ + - ]: 4 : GetImport(), nPrefix, rLocalName, xTOCPropertySet);
329 : 4 : break;
330 : :
331 : : case TEXT_INDEX_OBJECT:
332 : : pContext = new XMLIndexObjectSourceContext(
333 [ + - ]: 4 : GetImport(), nPrefix, rLocalName, xTOCPropertySet);
334 : 4 : break;
335 : :
336 : : case TEXT_INDEX_ALPHABETICAL:
337 : : pContext = new XMLIndexAlphabeticalSourceContext(
338 [ + - ]: 4 : GetImport(), nPrefix, rLocalName, xTOCPropertySet);
339 : 4 : break;
340 : :
341 : : case TEXT_INDEX_USER:
342 : : pContext = new XMLIndexUserSourceContext(
343 [ + - ]: 4 : GetImport(), nPrefix, rLocalName, xTOCPropertySet);
344 : 4 : break;
345 : :
346 : : case TEXT_INDEX_BIBLIOGRAPHY:
347 : : pContext = new XMLIndexBibliographySourceContext(
348 [ + - ]: 4 : GetImport(), nPrefix, rLocalName, xTOCPropertySet);
349 : 4 : break;
350 : :
351 : : case TEXT_INDEX_TABLE:
352 : : pContext = new XMLIndexTableSourceContext(
353 [ + - ]: 4 : GetImport(), nPrefix, rLocalName, xTOCPropertySet);
354 : 4 : break;
355 : :
356 : : case TEXT_INDEX_ILLUSTRATION:
357 : : pContext = new XMLIndexIllustrationSourceContext(
358 [ + - ]: 4 : GetImport(), nPrefix, rLocalName, xTOCPropertySet);
359 : 4 : break;
360 : :
361 : : default:
362 : : OSL_FAIL("index type not implemented");
363 : 28 : break;
364 : : }
365 : : }
366 : : // else: ignore
367 : : }
368 : : // else: no text: namespace -> ignore
369 : : }
370 : : // else: not valid -> ignore
371 : :
372 : : // default: ignore
373 [ - + ]: 56 : if (pContext == NULL)
374 : : {
375 : : pContext = SvXMLImportContext::CreateChildContext(nPrefix, rLocalName,
376 : 0 : xAttrList);
377 : : }
378 : :
379 : 56 : return pContext;
380 : : }
381 : :
382 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|