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 "XMLIndexTemplateContext.hxx"
21 #include "XMLIndexSimpleEntryContext.hxx"
22 #include "XMLIndexSpanEntryContext.hxx"
23 #include "XMLIndexTabStopEntryContext.hxx"
24 #include "XMLIndexBibliographyEntryContext.hxx"
25 #include "XMLIndexChapterInfoEntryContext.hxx"
26 #include <xmloff/xmlictxt.hxx>
27 #include <xmloff/xmlimp.hxx>
28 #include <xmloff/txtimp.hxx>
29 #include <xmloff/namespacemap.hxx>
30 #include <xmloff/xmlnamespace.hxx>
31 #include <xmloff/xmltoken.hxx>
32 #include <xmloff/xmluconv.hxx>
33 #include <xmloff/xmlement.hxx>
34 #include <tools/debug.hxx>
35 #include <rtl/ustring.hxx>
36 #include <sal/log.hxx>
37 #include <com/sun/star/container/XIndexReplace.hpp>
38 #include <com/sun/star/container/XNameContainer.hpp>
39 #include <com/sun/star/beans/XPropertySet.hpp>
42 using namespace ::std
;
43 using namespace ::xmloff::token
;
45 using ::com::sun::star::beans::XPropertySet
;
46 using ::com::sun::star::beans::PropertyValues
;
47 using ::com::sun::star::uno::Reference
;
48 using ::com::sun::star::uno::Sequence
;
49 using ::com::sun::star::uno::Any
;
50 using ::com::sun::star::xml::sax::XAttributeList
;
51 using ::com::sun::star::container::XIndexReplace
;
53 XMLIndexTemplateContext::XMLIndexTemplateContext(
55 Reference
<XPropertySet
> & rPropSet
,
57 const OUString
& rLocalName
,
58 const SvXMLEnumMapEntry
<sal_uInt16
>* pLevelNameMap
,
59 enum XMLTokenEnum eLevelAttrName
,
60 const char** pLevelStylePropMap
,
61 const bool* pAllowedTokenTypes
,
63 : SvXMLImportContext(rImport
, nPrfx
, rLocalName
)
64 , pOutlineLevelNameMap(pLevelNameMap
)
65 , eOutlineLevelAttrName(eLevelAttrName
)
66 , pOutlineLevelStylePropMap(pLevelStylePropMap
)
67 , pAllowedTokenTypesMap(pAllowedTokenTypes
)
68 , nOutlineLevel(1) // all indices have level 1 (0 is for header)
70 , bOutlineLevelOK(false)
72 , rPropertySet(rPropSet
)
74 DBG_ASSERT( ((XML_TOKEN_INVALID
!= eLevelAttrName
) && (nullptr != pLevelNameMap
))
75 || ((XML_TOKEN_INVALID
== eLevelAttrName
) && (nullptr == pLevelNameMap
)),
76 "need both, attribute name and value map, or neither" );
77 SAL_WARN_IF( nullptr == pOutlineLevelStylePropMap
, "xmloff", "need property name map" );
78 SAL_WARN_IF( nullptr == pAllowedTokenTypes
, "xmloff", "need allowed tokens map" );
80 // no map for outline-level? then use 1
81 if (nullptr == pLevelNameMap
)
84 bOutlineLevelOK
= true;
88 XMLIndexTemplateContext::~XMLIndexTemplateContext()
93 void XMLIndexTemplateContext::addTemplateEntry(
94 const PropertyValues
& aValues
)
96 aValueVector
.push_back(aValues
);
100 void XMLIndexTemplateContext::StartElement(
101 const Reference
<XAttributeList
> & xAttrList
)
103 // process two attributes: style-name, outline-level
104 sal_Int16 nLength
= xAttrList
->getLength();
105 for(sal_Int16 nAttr
= 0; nAttr
< nLength
; nAttr
++)
108 sal_uInt16 nPrefix
= GetImport().GetNamespaceMap().
109 GetKeyByAttrName( xAttrList
->getNameByIndex(nAttr
),
111 if (XML_NAMESPACE_TEXT
== nPrefix
)
113 if ( IsXMLToken( sLocalName
, XML_STYLE_NAME
) )
116 sStyleName
= xAttrList
->getValueByIndex(nAttr
);
119 else if (eOutlineLevelAttrName
!= XML_TOKEN_INVALID
)
121 // we have an attr name! Then see if we have the attr, too.
122 if (IsXMLToken(sLocalName
, eOutlineLevelAttrName
))
126 if (SvXMLUnitConverter::convertEnum(
127 nTmp
, xAttrList
->getValueByIndex(nAttr
),
128 pOutlineLevelNameMap
))
130 nOutlineLevel
= nTmp
;
131 bOutlineLevelOK
= true;
133 // else: illegal value -> ignore
135 // else: unknown attribute -> ignore
137 // else: we don't care about outline-level -> ignore
139 // else: attribute not in text namespace -> ignore
143 void XMLIndexTemplateContext::endFastElement(sal_Int32
)
145 if (!bOutlineLevelOK
)
148 const sal_Int32 nCount
= aValueVector
.size();
149 Sequence
<PropertyValues
> aValueSequence(nCount
);
150 for(sal_Int32 i
= 0; i
<nCount
; i
++)
152 aValueSequence
[i
] = aValueVector
[i
];
155 // get LevelFormat IndexReplace ...
156 Any aAny
= rPropertySet
->getPropertyValue("LevelFormat");
157 Reference
<XIndexReplace
> xIndexReplace
;
158 aAny
>>= xIndexReplace
;
161 xIndexReplace
->replaceByIndex(nOutlineLevel
, Any(aValueSequence
));
166 const char* pStyleProperty
=
167 pOutlineLevelStylePropMap
[nOutlineLevel
];
169 DBG_ASSERT(nullptr != pStyleProperty
, "need property name");
170 if (nullptr == pStyleProperty
)
173 OUString sDisplayStyleName
=
174 GetImport().GetStyleDisplayName(
175 XmlStyleFamily::TEXT_PARAGRAPH
,
177 // #i50288#: Check if style exists
178 const Reference
< css::container::XNameContainer
> & rStyles
=
179 GetImport().GetTextImport()->GetParaStyles();
181 rStyles
->hasByName( sDisplayStyleName
) )
183 rPropertySet
->setPropertyValue(
184 OUString::createFromAscii(pStyleProperty
), css::uno::Any(sDisplayStyleName
));
189 /// template token types; used for aTokenTypeMap parameter
190 enum TemplateTokenType
192 XML_TOK_INDEX_TYPE_ENTRY_TEXT
= 0,
193 XML_TOK_INDEX_TYPE_TAB_STOP
,
194 XML_TOK_INDEX_TYPE_TEXT
,
195 XML_TOK_INDEX_TYPE_PAGE_NUMBER
,
196 XML_TOK_INDEX_TYPE_CHAPTER
,
197 XML_TOK_INDEX_TYPE_LINK_START
,
198 XML_TOK_INDEX_TYPE_LINK_END
,
199 XML_TOK_INDEX_TYPE_BIBLIOGRAPHY
204 SvXMLEnumMapEntry
<TemplateTokenType
> const aTemplateTokenTypeMap
[] =
206 { XML_INDEX_ENTRY_TEXT
, XML_TOK_INDEX_TYPE_ENTRY_TEXT
},
207 { XML_INDEX_ENTRY_TAB_STOP
, XML_TOK_INDEX_TYPE_TAB_STOP
},
208 { XML_INDEX_ENTRY_SPAN
, XML_TOK_INDEX_TYPE_TEXT
},
209 { XML_INDEX_ENTRY_PAGE_NUMBER
, XML_TOK_INDEX_TYPE_PAGE_NUMBER
},
210 { XML_INDEX_ENTRY_CHAPTER
, XML_TOK_INDEX_TYPE_CHAPTER
},
211 { XML_INDEX_ENTRY_LINK_START
, XML_TOK_INDEX_TYPE_LINK_START
},
212 { XML_INDEX_ENTRY_LINK_END
, XML_TOK_INDEX_TYPE_LINK_END
},
213 { XML_INDEX_ENTRY_BIBLIOGRAPHY
, XML_TOK_INDEX_TYPE_BIBLIOGRAPHY
},
214 { XML_TOKEN_INVALID
, TemplateTokenType(0) }
217 SvXMLImportContextRef
XMLIndexTemplateContext::CreateChildContext(
219 const OUString
& rLocalName
,
220 const Reference
<XAttributeList
> & /*xAttrList*/ )
222 SvXMLImportContext
* pContext
= nullptr;
224 if (XML_NAMESPACE_TEXT
== nPrefix
|| XML_NAMESPACE_LO_EXT
== nPrefix
)
226 TemplateTokenType nToken
;
227 if (SvXMLUnitConverter::convertEnum(nToken
, rLocalName
,
228 aTemplateTokenTypeMap
))
230 // can this index accept this kind of token?
231 if (pAllowedTokenTypesMap
[nToken
])
235 case XML_TOK_INDEX_TYPE_ENTRY_TEXT
:
236 pContext
= new XMLIndexSimpleEntryContext(
237 GetImport(), "TokenEntryText", *this,
238 nPrefix
, rLocalName
);
241 case XML_TOK_INDEX_TYPE_PAGE_NUMBER
:
242 pContext
= new XMLIndexSimpleEntryContext(
243 GetImport(), "TokenPageNumber", *this,
244 nPrefix
, rLocalName
);
247 case XML_TOK_INDEX_TYPE_LINK_START
:
248 pContext
= new XMLIndexSimpleEntryContext(
249 GetImport(), "TokenHyperlinkStart", *this,
250 nPrefix
, rLocalName
);
253 case XML_TOK_INDEX_TYPE_LINK_END
:
254 pContext
= new XMLIndexSimpleEntryContext(
255 GetImport(), "TokenHyperlinkEnd", *this,
256 nPrefix
, rLocalName
);
259 case XML_TOK_INDEX_TYPE_TEXT
:
260 pContext
= new XMLIndexSpanEntryContext(
261 GetImport(), *this, nPrefix
, rLocalName
);
264 case XML_TOK_INDEX_TYPE_TAB_STOP
:
265 pContext
= new XMLIndexTabStopEntryContext(
266 GetImport(), *this, nPrefix
, rLocalName
);
269 case XML_TOK_INDEX_TYPE_BIBLIOGRAPHY
:
270 pContext
= new XMLIndexBibliographyEntryContext(
271 GetImport(), *this, nPrefix
, rLocalName
);
274 case XML_TOK_INDEX_TYPE_CHAPTER
:
275 pContext
= new XMLIndexChapterInfoEntryContext(
276 GetImport(), *this, nPrefix
, rLocalName
, bTOC
);
292 // maps for the XMLIndexTemplateContext constructor
295 // table of content and user defined index:
297 const SvXMLEnumMapEntry
<sal_uInt16
> aSvLevelNameTOCMap
[] =
309 { XML_TOKEN_INVALID
, 0 }
312 const char* aLevelStylePropNameTOCMap
[] =
313 { nullptr, "ParaStyleLevel1", "ParaStyleLevel2", "ParaStyleLevel3",
314 "ParaStyleLevel4", "ParaStyleLevel5", "ParaStyleLevel6",
315 "ParaStyleLevel7", "ParaStyleLevel8", "ParaStyleLevel9",
316 "ParaStyleLevel10", nullptr };
318 const bool aAllowedTokenTypesTOC
[] =
320 true, // XML_TOK_INDEX_TYPE_ENTRY_TEXT =
321 true, // XML_TOK_INDEX_TYPE_TAB_STOP,
322 true, // XML_TOK_INDEX_TYPE_TEXT,
323 true, // XML_TOK_INDEX_TYPE_PAGE_NUMBER,
324 true, // XML_TOK_INDEX_TYPE_CHAPTER,
325 true, // XML_TOK_INDEX_TYPE_LINK_START,
326 true, // XML_TOK_INDEX_TYPE_LINK_END,
327 false // XML_TOK_INDEX_TYPE_BIBLIOGRAPHY
330 const bool aAllowedTokenTypesUser
[] =
332 true, // XML_TOK_INDEX_TYPE_ENTRY_TEXT =
333 true, // XML_TOK_INDEX_TYPE_TAB_STOP,
334 true, // XML_TOK_INDEX_TYPE_TEXT,
335 true, // XML_TOK_INDEX_TYPE_PAGE_NUMBER,
336 true, // XML_TOK_INDEX_TYPE_CHAPTER,
337 true, // XML_TOK_INDEX_TYPE_LINK_START,
338 true, // XML_TOK_INDEX_TYPE_LINK_END,
339 false // XML_TOK_INDEX_TYPE_BIBLIOGRAPHY
343 // alphabetical index
345 const SvXMLEnumMapEntry
<sal_uInt16
> aLevelNameAlphaMap
[] =
347 { XML_SEPARATOR
, 1 },
351 { XML_TOKEN_INVALID
, 0 }
354 const char* aLevelStylePropNameAlphaMap
[] =
355 { nullptr, "ParaStyleSeparator", "ParaStyleLevel1", "ParaStyleLevel2",
356 "ParaStyleLevel3", nullptr };
358 const bool aAllowedTokenTypesAlpha
[] =
360 true, // XML_TOK_INDEX_TYPE_ENTRY_TEXT =
361 true, // XML_TOK_INDEX_TYPE_TAB_STOP,
362 true, // XML_TOK_INDEX_TYPE_TEXT,
363 true, // XML_TOK_INDEX_TYPE_PAGE_NUMBER,
364 true, // XML_TOK_INDEX_TYPE_CHAPTER,
365 false, // XML_TOK_INDEX_TYPE_LINK_START,
366 false, // XML_TOK_INDEX_TYPE_LINK_END,
367 false // XML_TOK_INDEX_TYPE_BIBLIOGRAPHY
371 // bibliography index:
373 const SvXMLEnumMapEntry
<sal_uInt16
> aLevelNameBibliographyMap
[] =
378 { XML_CONFERENCE
, 4 },
386 { XML_INCOLLECTION
, 12 },
387 { XML_INPROCEEDINGS
, 13 },
390 { XML_MASTERSTHESIS
, 16 },
392 { XML_PHDTHESIS
, 18 },
393 { XML_PROCEEDINGS
, 19 },
394 { XML_TECHREPORT
, 20 },
395 { XML_UNPUBLISHED
, 21 },
397 { XML_TOKEN_INVALID
, 0 }
400 // TODO: replace with real property names, when available
401 const char* aLevelStylePropNameBibliographyMap
[] =
403 nullptr, "ParaStyleLevel1", "ParaStyleLevel1", "ParaStyleLevel1",
404 "ParaStyleLevel1", "ParaStyleLevel1", "ParaStyleLevel1",
405 "ParaStyleLevel1", "ParaStyleLevel1", "ParaStyleLevel1",
406 "ParaStyleLevel1", "ParaStyleLevel1", "ParaStyleLevel1",
407 "ParaStyleLevel1", "ParaStyleLevel1", "ParaStyleLevel1",
408 "ParaStyleLevel1", "ParaStyleLevel1", "ParaStyleLevel1",
409 "ParaStyleLevel1", "ParaStyleLevel1", "ParaStyleLevel1",
410 "ParaStyleLevel1", nullptr };
412 const bool aAllowedTokenTypesBibliography
[] =
414 true, // XML_TOK_INDEX_TYPE_ENTRY_TEXT =
415 true, // XML_TOK_INDEX_TYPE_TAB_STOP,
416 true, // XML_TOK_INDEX_TYPE_TEXT,
417 true, // XML_TOK_INDEX_TYPE_PAGE_NUMBER,
418 false, // XML_TOK_INDEX_TYPE_CHAPTER,
419 false, // XML_TOK_INDEX_TYPE_LINK_START,
420 false, // XML_TOK_INDEX_TYPE_LINK_END,
421 true // XML_TOK_INDEX_TYPE_BIBLIOGRAPHY
425 // table, illustration and object index
428 const SvXMLEnumMapEntry
<sal_uInt16
>* aLevelNameTableMap
= nullptr;
430 const char* aLevelStylePropNameTableMap
[] =
431 { nullptr, "ParaStyleLevel1", nullptr };
433 const bool aAllowedTokenTypesTable
[] =
435 true, // XML_TOK_INDEX_TYPE_ENTRY_TEXT =
436 true, // XML_TOK_INDEX_TYPE_TAB_STOP,
437 true, // XML_TOK_INDEX_TYPE_TEXT,
438 true, // XML_TOK_INDEX_TYPE_PAGE_NUMBER,
439 true, // XML_TOK_INDEX_TYPE_CHAPTER,
440 true, // XML_TOK_INDEX_TYPE_LINK_START,
441 true, // XML_TOK_INDEX_TYPE_LINK_END,
442 false // XML_TOK_INDEX_TYPE_BIBLIOGRAPHY
445 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */