1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_xmloff.hxx"
26 #include "XMLSectionExport.hxx"
27 #include <rtl/ustring.hxx>
28 #include <rtl/ustrbuf.hxx>
29 
30 #include <vector>
31 
32 
33 #include <com/sun/star/lang/XServiceInfo.hpp>
34 #include <com/sun/star/lang/Locale.hpp>
35 #include <com/sun/star/container/XIndexReplace.hpp>
36 #include <com/sun/star/beans/XPropertySet.hpp>
37 #include <com/sun/star/beans/PropertyValue.hpp>
38 #include <com/sun/star/beans/PropertyValues.hpp>
39 #include <com/sun/star/beans/PropertyState.hpp>
40 #include <com/sun/star/text/XText.hpp>
41 #include <com/sun/star/text/XTextSection.hpp>
42 #include <com/sun/star/text/SectionFileLink.hpp>
43 #include <com/sun/star/container/XNamed.hpp>
44 #include <com/sun/star/container/XNameAccess.hpp>
45 #include <com/sun/star/text/XDocumentIndex.hpp>
46 #include <com/sun/star/uno/XInterface.hpp>
47 #include <com/sun/star/text/BibliographyDataField.hpp>
48 #include <com/sun/star/text/XTextFieldsSupplier.hpp>
49 #include <com/sun/star/text/XChapterNumberingSupplier.hpp>
50 #include <com/sun/star/text/ChapterFormat.hpp> //i90246
51 #include <xmloff/xmltoken.hxx>
52 #include "xmloff/xmlnmspe.hxx"
53 #include <xmloff/families.hxx>
54 #include <xmloff/xmluconv.hxx>
55 #include <xmloff/nmspmap.hxx>
56 #include <xmloff/xmlexp.hxx>
57 #include <xmloff/xmltkmap.hxx>
58 #include "txtflde.hxx"
59 
60 
61 
62 using namespace ::com::sun::star;
63 using namespace ::com::sun::star::text;
64 using namespace ::com::sun::star::uno;
65 using namespace ::std;
66 using namespace ::xmloff::token;
67 
68 using ::rtl::OUString;
69 using ::rtl::OUStringBuffer;
70 using ::com::sun::star::beans::XPropertySet;
71 using ::com::sun::star::beans::PropertyValue;
72 using ::com::sun::star::beans::PropertyValues;
73 using ::com::sun::star::beans::PropertyState;
74 using ::com::sun::star::container::XIndexReplace;
75 using ::com::sun::star::container::XNameAccess;
76 using ::com::sun::star::container::XNamed;
77 using ::com::sun::star::lang::XServiceInfo;
78 using ::com::sun::star::lang::Locale;
79 using ::com::sun::star::uno::XInterface;
80 
81 
XMLSectionExport(SvXMLExport & rExp,XMLTextParagraphExport & rParaExp)82 XMLSectionExport::XMLSectionExport(
83 	SvXMLExport& rExp,
84 	XMLTextParagraphExport& rParaExp)
85 :	sCondition(RTL_CONSTASCII_USTRINGPARAM("Condition"))
86 ,	sCreateFromChapter(RTL_CONSTASCII_USTRINGPARAM("CreateFromChapter"))
87 ,	sCreateFromEmbeddedObjects(RTL_CONSTASCII_USTRINGPARAM("CreateFromEmbeddedObjects"))
88 ,	sCreateFromGraphicObjects(RTL_CONSTASCII_USTRINGPARAM("CreateFromGraphicObjects"))
89 ,	sCreateFromLabels(RTL_CONSTASCII_USTRINGPARAM("CreateFromLabels"))
90 ,	sCreateFromMarks(RTL_CONSTASCII_USTRINGPARAM("CreateFromMarks"))
91 ,	sCreateFromOtherEmbeddedObjects(RTL_CONSTASCII_USTRINGPARAM("CreateFromOtherEmbeddedObjects"))
92 ,	sCreateFromOutline(RTL_CONSTASCII_USTRINGPARAM("CreateFromOutline"))
93 ,	sCreateFromStarCalc(RTL_CONSTASCII_USTRINGPARAM("CreateFromStarCalc"))
94 ,	sCreateFromStarChart(RTL_CONSTASCII_USTRINGPARAM("CreateFromStarChart"))
95 ,	sCreateFromStarDraw(RTL_CONSTASCII_USTRINGPARAM("CreateFromStarDraw"))
96 ,	sCreateFromStarImage(RTL_CONSTASCII_USTRINGPARAM("CreateFromStarImage"))
97 ,	sCreateFromStarMath(RTL_CONSTASCII_USTRINGPARAM("CreateFromStarMath"))
98 ,	sCreateFromTables(RTL_CONSTASCII_USTRINGPARAM("CreateFromTables"))
99 ,	sCreateFromTextFrames(RTL_CONSTASCII_USTRINGPARAM("CreateFromTextFrames"))
100 ,	sDdeCommandElement(RTL_CONSTASCII_USTRINGPARAM("DDECommandElement"))
101 ,	sDdeCommandFile(RTL_CONSTASCII_USTRINGPARAM("DDECommandFile"))
102 ,	sDdeCommandType(RTL_CONSTASCII_USTRINGPARAM("DDECommandType"))
103 ,	sFileLink(RTL_CONSTASCII_USTRINGPARAM("FileLink"))
104 ,	sIsCaseSensitive(RTL_CONSTASCII_USTRINGPARAM("IsCaseSensitive"))
105 ,	sIsProtected(RTL_CONSTASCII_USTRINGPARAM("IsProtected"))
106 ,	sIsVisible(RTL_CONSTASCII_USTRINGPARAM("IsVisible"))
107 ,	sLabelCategory(RTL_CONSTASCII_USTRINGPARAM("LabelCategory"))
108 ,	sLabelDisplayType(RTL_CONSTASCII_USTRINGPARAM("LabelDisplayType"))
109 ,	sLevel(RTL_CONSTASCII_USTRINGPARAM("Level"))
110 ,	sLevelFormat(RTL_CONSTASCII_USTRINGPARAM("LevelFormat"))
111 ,	sLevelParagraphStyles(RTL_CONSTASCII_USTRINGPARAM("LevelParagraphStyles"))
112 ,	sLinkRegion(RTL_CONSTASCII_USTRINGPARAM("LinkRegion"))
113 ,	sMainEntryCharacterStyleName(RTL_CONSTASCII_USTRINGPARAM("MainEntryCharacterStyleName"))
114 ,	sParaStyleHeading(RTL_CONSTASCII_USTRINGPARAM("ParaStyleHeading"))
115 ,	sParaStyleLevel(RTL_CONSTASCII_USTRINGPARAM("ParaStyleLevel"))
116 ,	sTitle(RTL_CONSTASCII_USTRINGPARAM("Title"))
117 ,	sName(RTL_CONSTASCII_USTRINGPARAM("Name"))
118 ,	sUseAlphabeticalSeparators(RTL_CONSTASCII_USTRINGPARAM("UseAlphabeticalSeparators"))
119 ,	sUseCombinedEntries(RTL_CONSTASCII_USTRINGPARAM("UseCombinedEntries"))
120 ,	sUseDash(RTL_CONSTASCII_USTRINGPARAM("UseDash"))
121 ,	sUseKeyAsEntry(RTL_CONSTASCII_USTRINGPARAM("UseKeyAsEntry"))
122 ,	sUseLevelFromSource(RTL_CONSTASCII_USTRINGPARAM("UseLevelFromSource"))
123 ,	sUsePP(RTL_CONSTASCII_USTRINGPARAM("UsePP"))
124 ,	sUseUpperCase(RTL_CONSTASCII_USTRINGPARAM("UseUpperCase"))
125 ,	sIsCommaSeparated(RTL_CONSTASCII_USTRINGPARAM("IsCommaSeparated"))
126 ,	sIsAutomaticUpdate(RTL_CONSTASCII_USTRINGPARAM("IsAutomaticUpdate"))
127 ,	sIsRelativeTabstops(RTL_CONSTASCII_USTRINGPARAM("IsRelativeTabstops"))
128 ,	sCreateFromLevelParagraphStyles(RTL_CONSTASCII_USTRINGPARAM("CreateFromLevelParagraphStyles"))
129 ,	sDocumentIndex(RTL_CONSTASCII_USTRINGPARAM("DocumentIndex"))
130 ,	sContentSection(RTL_CONSTASCII_USTRINGPARAM("ContentSection"))
131 ,	sHeaderSection(RTL_CONSTASCII_USTRINGPARAM("HeaderSection"))
132 
133 ,	sTextSection(RTL_CONSTASCII_USTRINGPARAM("TextSection"))
134 ,	sIsGlobalDocumentSection(RTL_CONSTASCII_USTRINGPARAM("IsGlobalDocumentSection"))
135 ,	sProtectionKey(RTL_CONSTASCII_USTRINGPARAM("ProtectionKey"))
136 ,	sSortAlgorithm(RTL_CONSTASCII_USTRINGPARAM("SortAlgorithm"))
137 ,	sLocale(RTL_CONSTASCII_USTRINGPARAM("Locale"))
138 ,	sUserIndexName(RTL_CONSTASCII_USTRINGPARAM("UserIndexName"))
139 
140 ,	sIsCurrentlyVisible(RTL_CONSTASCII_USTRINGPARAM("IsCurrentlyVisible"))
141 ,	sHeadingStyleName(RTL_CONSTASCII_USTRINGPARAM("HeadingStyleName"))
142 
143 ,	rExport(rExp)
144 ,	rParaExport(rParaExp)
145 ,	bHeadingDummiesExported( sal_False )
146 {
147 }
148 
149 
ExportSectionStart(const Reference<XTextSection> & rSection,sal_Bool bAutoStyles)150 void XMLSectionExport::ExportSectionStart(
151 	const Reference<XTextSection> & rSection,
152 	sal_Bool bAutoStyles)
153 {
154 	Reference<XPropertySet> xPropertySet(rSection, UNO_QUERY);
155 
156 	// always export section (auto) style
157 	if (bAutoStyles)
158 	{
159 		// get PropertySet and add section style
160 		GetParaExport().Add( XML_STYLE_FAMILY_TEXT_SECTION, xPropertySet );
161 	}
162 	else
163 	{
164 		// always export section style
165 		GetExport().AddAttribute(XML_NAMESPACE_TEXT, XML_STYLE_NAME,
166 									 GetParaExport().Find(
167 									 XML_STYLE_FAMILY_TEXT_SECTION,
168 									 xPropertySet, sEmpty ) );
169 
170         // xml:id for RDF metadata
171         GetExport().AddAttributeXmlId(rSection);
172 
173 		// export index or regular section
174 		Reference<XDocumentIndex> xIndex;
175 		if (GetIndex(rSection, xIndex))
176 		{
177 			if (xIndex.is())
178 			{
179 				// we are an index
180 				ExportIndexStart(xIndex);
181 			}
182 			else
183 			{
184 				// we are an index header
185 				ExportIndexHeaderStart(rSection);
186 			}
187 		}
188 		else
189 		{
190 			// we are not an index
191 			ExportRegularSectionStart(rSection);
192 		}
193 	}
194 }
195 
GetIndex(const Reference<XTextSection> & rSection,Reference<XDocumentIndex> & rIndex) const196 sal_Bool XMLSectionExport::GetIndex(
197 	const Reference<XTextSection> & rSection,
198 	Reference<XDocumentIndex> & rIndex) const
199 {
200 	// first, reset result
201 	sal_Bool bRet = sal_False;
202 	rIndex = NULL;
203 
204 	// get section Properties
205 	Reference<XPropertySet> xSectionPropSet(rSection, UNO_QUERY);
206 
207 	// then check if this section happens to be inside an index
208 	if (xSectionPropSet->getPropertySetInfo()->
209 									hasPropertyByName(sDocumentIndex))
210 	{
211 		Any aAny = xSectionPropSet->getPropertyValue(sDocumentIndex);
212 		Reference<XDocumentIndex> xDocumentIndex;
213 		aAny >>= xDocumentIndex;
214 
215 		// OK, are we inside of an index
216 		if (xDocumentIndex.is())
217 		{
218 			// is the enclosing index identical with "our" section?
219 			Reference<XPropertySet> xIndexPropSet(xDocumentIndex, UNO_QUERY);
220 			aAny = xIndexPropSet->getPropertyValue(sContentSection);
221 			Reference<XTextSection> xEnclosingSection;
222 			aAny >>= xEnclosingSection;
223 
224 			// if the enclosing section is "our" section, then we are an index!
225 			if (rSection == xEnclosingSection)
226 			{
227 				rIndex = xDocumentIndex;
228 				bRet = sal_True;
229 			}
230 			// else: index header or regular section
231 
232 			// is the enclosing index identical with the header section?
233 			aAny = xIndexPropSet->getPropertyValue(sHeaderSection);
234 			// now mis-named: contains header section
235 			aAny >>= xEnclosingSection;
236 
237 			// if the enclosing section is "our" section, then we are an index!
238 			if (rSection == xEnclosingSection)
239 			{
240 				bRet = sal_True;
241 			}
242 			// else: regular section
243 		}
244 		// else: we aren't even inside of an index
245 	}
246 	// else: we don't even know what an index is.
247 
248 	return bRet;
249 }
250 
251 
ExportSectionEnd(const Reference<XTextSection> & rSection,sal_Bool bAutoStyles)252 void XMLSectionExport::ExportSectionEnd(
253 	const Reference<XTextSection> & rSection,
254 	sal_Bool bAutoStyles)
255 {
256 	// no end section for styles
257 	if (!bAutoStyles)
258 	{
259 		enum XMLTokenEnum eElement = XML_TOKEN_INVALID;
260 
261 		// export index or regular section end
262 		Reference<XDocumentIndex> xIndex;
263 		if (GetIndex(rSection, xIndex))
264 		{
265 			if (xIndex.is())
266 			{
267 				// index end: close index body element
268 				GetExport().EndElement( XML_NAMESPACE_TEXT,	XML_INDEX_BODY,
269                                         sal_True );
270 				GetExport().IgnorableWhitespace();
271 
272 				switch (MapSectionType(xIndex->getServiceName()))
273 				{
274 					case TEXT_SECTION_TYPE_TOC:
275 						eElement = XML_TABLE_OF_CONTENT;
276 						break;
277 
278 					case TEXT_SECTION_TYPE_ILLUSTRATION:
279 						eElement = XML_ILLUSTRATION_INDEX;
280 						break;
281 
282 					case TEXT_SECTION_TYPE_ALPHABETICAL:
283 						eElement = XML_ALPHABETICAL_INDEX;
284 						break;
285 
286 					case TEXT_SECTION_TYPE_TABLE:
287 						eElement = XML_TABLE_INDEX;
288 						break;
289 
290 					case TEXT_SECTION_TYPE_OBJECT:
291 						eElement = XML_OBJECT_INDEX;
292 						break;
293 
294 					case TEXT_SECTION_TYPE_USER:
295 						eElement = XML_USER_INDEX;
296 						break;
297 
298 					case TEXT_SECTION_TYPE_BIBLIOGRAPHY:
299 						eElement = XML_BIBLIOGRAPHY;
300 						break;
301 
302 					default:
303 						OSL_ENSURE(false, "unknown index type");
304 						// default: skip index!
305 						break;
306 				}
307 			}
308 			else
309 			{
310 				eElement = XML_INDEX_TITLE;
311 			}
312 		}
313 		else
314 		{
315 			eElement = XML_SECTION;
316 		}
317 
318 		if (XML_TOKEN_INVALID != eElement)
319 		{
320 			// any old attributes?
321 			GetExport().CheckAttrList();
322 
323 			// element surrounded by whitespace
324 			GetExport().EndElement( XML_NAMESPACE_TEXT,	eElement, sal_True);
325 			GetExport().IgnorableWhitespace();
326 		}
327 		else
328 		{
329 			OSL_ENSURE(false, "Need element name!");
330 		}
331 	}
332 	// else: autostyles -> ignore
333 }
334 
ExportIndexStart(const Reference<XDocumentIndex> & rIndex)335 void XMLSectionExport::ExportIndexStart(
336 	const Reference<XDocumentIndex> & rIndex)
337 {
338 	// get PropertySet
339 	Reference<XPropertySet> xPropertySet(rIndex, UNO_QUERY);
340 
341 	switch (MapSectionType(rIndex->getServiceName()))
342 	{
343 		case TEXT_SECTION_TYPE_TOC:
344 			ExportTableOfContentStart(xPropertySet);
345 			break;
346 
347 		case TEXT_SECTION_TYPE_ILLUSTRATION:
348 			ExportIllustrationIndexStart(xPropertySet);
349 			break;
350 
351 		case TEXT_SECTION_TYPE_ALPHABETICAL:
352 			ExportAlphabeticalIndexStart(xPropertySet);
353 			break;
354 
355 		case TEXT_SECTION_TYPE_TABLE:
356 			ExportTableIndexStart(xPropertySet);
357 			break;
358 
359 		case TEXT_SECTION_TYPE_OBJECT:
360 			ExportObjectIndexStart(xPropertySet);
361 			break;
362 
363 		case TEXT_SECTION_TYPE_USER:
364 			ExportUserIndexStart(xPropertySet);
365 			break;
366 
367 		case TEXT_SECTION_TYPE_BIBLIOGRAPHY:
368 			ExportBibliographyStart(xPropertySet);
369 			break;
370 
371 		default:
372 			// skip index
373 			OSL_ENSURE(false, "unknown index type");
374 			break;
375 	}
376 }
377 
ExportIndexHeaderStart(const Reference<XTextSection> & rSection)378 void XMLSectionExport::ExportIndexHeaderStart(
379 	const Reference<XTextSection> & rSection)
380 {
381 	// export name, dammit!
382 	Reference<XNamed> xName(rSection, UNO_QUERY);
383 	GetExport().AddAttribute(XML_NAMESPACE_TEXT, XML_NAME, xName->getName());
384 
385 	// format already handled -> export only start element
386 	GetExport().StartElement( XML_NAMESPACE_TEXT, XML_INDEX_TITLE, sal_True );
387 	GetExport().IgnorableWhitespace();
388 }
389 
390 
391 SvXMLEnumStringMapEntry __READONLY_DATA aIndexTypeMap[] =
392 {
393 	ENUM_STRING_MAP_ENTRY( "com.sun.star.text.ContentIndex", TEXT_SECTION_TYPE_TOC ),
394 	ENUM_STRING_MAP_ENTRY( "com.sun.star.text.DocumentIndex", TEXT_SECTION_TYPE_ALPHABETICAL ),
395 	ENUM_STRING_MAP_ENTRY( "com.sun.star.text.TableIndex", TEXT_SECTION_TYPE_TABLE ),
396 	ENUM_STRING_MAP_ENTRY( "com.sun.star.text.ObjectIndex", TEXT_SECTION_TYPE_OBJECT ),
397 	ENUM_STRING_MAP_ENTRY( "com.sun.star.text.Bibliography", TEXT_SECTION_TYPE_BIBLIOGRAPHY ),
398 	ENUM_STRING_MAP_ENTRY( "com.sun.star.text.UserIndex", TEXT_SECTION_TYPE_USER ),
399 	ENUM_STRING_MAP_ENTRY( "com.sun.star.text.IllustrationsIndex", TEXT_SECTION_TYPE_ILLUSTRATION ),
400     ENUM_STRING_MAP_END()
401 };
402 
MapSectionType(const OUString & rServiceName)403 enum SectionTypeEnum XMLSectionExport::MapSectionType(
404 	const OUString& rServiceName)
405 {
406 	enum SectionTypeEnum eType = TEXT_SECTION_TYPE_UNKNOWN;
407 
408 	sal_uInt16 nTmp;
409 	if (SvXMLUnitConverter::convertEnum(nTmp, rServiceName, aIndexTypeMap))
410 	{
411 		eType = (enum SectionTypeEnum)nTmp;
412 	}
413 
414 	// TODO: index header section types, etc.
415 
416 	return eType;
417 }
418 
ExportRegularSectionStart(const Reference<XTextSection> & rSection)419 void XMLSectionExport::ExportRegularSectionStart(
420 	const Reference<XTextSection> & rSection)
421 {
422 	// style name already handled in ExportSectionStart(...)
423 
424 	Reference<XNamed> xName(rSection, UNO_QUERY);
425 	GetExport().AddAttribute(XML_NAMESPACE_TEXT, XML_NAME, xName->getName());
426 
427 	// get XPropertySet for other values
428 	Reference<XPropertySet> xPropSet(rSection, UNO_QUERY);
429 	Any aAny;
430 
431 	// condition and display
432 	aAny = xPropSet->getPropertyValue(sCondition);
433 	OUString sCond;
434 	aAny >>= sCond;
435 	enum XMLTokenEnum eDisplay = XML_TOKEN_INVALID;
436 	if (sCond.getLength() > 0)
437 	{
438 		OUString sQValue =
439 			GetExport().GetNamespaceMap().GetQNameByKey( XML_NAMESPACE_OOOW,
440 														 sCond, sal_False );
441 		GetExport().AddAttribute(XML_NAMESPACE_TEXT, XML_CONDITION, sQValue);
442 		eDisplay = XML_CONDITION;
443 
444         // #97450# store hidden-status (of conditional sections only)
445         aAny = xPropSet->getPropertyValue(sIsCurrentlyVisible);
446         if (! *(sal_Bool*)aAny.getValue())
447         {
448             GetExport().AddAttribute(XML_NAMESPACE_TEXT, XML_IS_HIDDEN,
449                                      XML_TRUE);
450         }
451 	}
452 	else
453 	{
454 		eDisplay = XML_NONE;
455 	}
456 	aAny = xPropSet->getPropertyValue(sIsVisible);
457 	if (! *(sal_Bool*)aAny.getValue())
458 	{
459 		GetExport().AddAttribute(XML_NAMESPACE_TEXT, XML_DISPLAY, eDisplay);
460 	}
461 
462 	// protect + protection key
463 	aAny = xPropSet->getPropertyValue(sIsProtected);
464 	if (*(sal_Bool*)aAny.getValue())
465 	{
466 		GetExport().AddAttribute(XML_NAMESPACE_TEXT, XML_PROTECTED, XML_TRUE);
467 	}
468 	Sequence<sal_Int8> aPassword;
469 	xPropSet->getPropertyValue(sProtectionKey) >>= aPassword;
470 	if (aPassword.getLength() > 0)
471 	{
472 		OUStringBuffer aBuffer;
473 		SvXMLUnitConverter::encodeBase64(aBuffer, aPassword);
474 		GetExport().AddAttribute(XML_NAMESPACE_TEXT, XML_PROTECTION_KEY,
475 								 aBuffer.makeStringAndClear());
476 	}
477 
478 	// export element
479 	GetExport().IgnorableWhitespace();
480 	GetExport().StartElement( XML_NAMESPACE_TEXT, XML_SECTION, sal_True );
481 
482 	// data source
483 	// unfortunately, we have to test all relevant strings for non-zero length
484 	aAny = xPropSet->getPropertyValue(sFileLink);
485 	SectionFileLink aFileLink;
486 	aAny >>= aFileLink;
487 
488 	aAny = xPropSet->getPropertyValue(sLinkRegion);
489 	OUString sRegionName;
490 	aAny >>= sRegionName;
491 
492 	if ( (aFileLink.FileURL.getLength() > 0) ||
493 		 (aFileLink.FilterName.getLength() > 0) ||
494 		 (sRegionName.getLength() > 0) )
495 	{
496 		if (aFileLink.FileURL.getLength() > 0)
497 		{
498 			GetExport().AddAttribute(XML_NAMESPACE_XLINK, XML_HREF,
499 									 GetExport().GetRelativeReference( aFileLink.FileURL) );
500 		}
501 
502 		if (aFileLink.FilterName.getLength() > 0)
503 		{
504 			GetExport().AddAttribute(XML_NAMESPACE_TEXT, XML_FILTER_NAME,
505 									 aFileLink.FilterName);
506 		}
507 
508 		if (sRegionName.getLength() > 0)
509 		{
510 			GetExport().AddAttribute(XML_NAMESPACE_TEXT, XML_SECTION_NAME,
511 									 sRegionName);
512 		}
513 
514 		SvXMLElementExport aElem(GetExport(),
515 								 XML_NAMESPACE_TEXT, XML_SECTION_SOURCE,
516 								 sal_True, sal_True);
517 	}
518 	else
519 	{
520 		// check for DDE first
521 		if (xPropSet->getPropertySetInfo()->hasPropertyByName(sDdeCommandFile))
522 		{
523 			// data source DDE
524 			// unfortunately, we have to test all relevant strings for
525 			// non-zero length
526 			aAny = xPropSet->getPropertyValue(sDdeCommandFile);
527 			OUString sApplication;
528 			aAny >>= sApplication;
529 			aAny = xPropSet->getPropertyValue(sDdeCommandType);
530 			OUString sTopic;
531 			aAny >>= sTopic;
532 			aAny = xPropSet->getPropertyValue(sDdeCommandElement);
533 			OUString sItem;
534 			aAny >>= sItem;
535 
536 			if ( (sApplication.getLength() > 0) ||
537 				 (sTopic.getLength() > 0) ||
538 				 (sItem.getLength() > 0 )   )
539 			{
540 				GetExport().AddAttribute(XML_NAMESPACE_OFFICE,
541 										 XML_DDE_APPLICATION, sApplication);
542 				GetExport().AddAttribute(XML_NAMESPACE_OFFICE, XML_DDE_TOPIC,
543 										 sTopic);
544 				GetExport().AddAttribute(XML_NAMESPACE_OFFICE, XML_DDE_ITEM,
545 										 sItem);
546 
547 				aAny = xPropSet->getPropertyValue(sIsAutomaticUpdate);
548 				if (*(sal_Bool*)aAny.getValue())
549 				{
550 					GetExport().AddAttribute(XML_NAMESPACE_OFFICE,
551                                              XML_AUTOMATIC_UPDATE, XML_TRUE);
552 				}
553 
554 				SvXMLElementExport aElem(GetExport(),
555 										 XML_NAMESPACE_OFFICE,
556 										 XML_DDE_SOURCE, sal_True, sal_True);
557 			}
558 			// else: no DDE data source
559 		}
560 		// else: no DDE on this system
561 	}
562 }
563 
ExportTableOfContentStart(const Reference<XPropertySet> & rPropertySet)564 void XMLSectionExport::ExportTableOfContentStart(
565 	const Reference<XPropertySet> & rPropertySet)
566 {
567 	// export TOC element start
568 	ExportBaseIndexStart(XML_TABLE_OF_CONTENT, rPropertySet);
569 
570 	// scope for table-of-content-source element
571 	{
572 
573 		Any aAny;
574 
575 		// TOC specific index source attributes:
576 
577         // outline-level: 1..10
578         sal_Int16 nLevel = sal_Int16();
579         if( rPropertySet->getPropertyValue(sLevel) >>= nLevel )
580         {
581             OUStringBuffer sBuffer;
582             SvXMLUnitConverter::convertNumber(sBuffer, (sal_Int32)nLevel);
583             GetExport().AddAttribute(XML_NAMESPACE_TEXT,
584                                      XML_OUTLINE_LEVEL,
585                                      sBuffer.makeStringAndClear());
586         }
587 
588         // use outline level
589         ExportBoolean(rPropertySet, sCreateFromOutline,
590                           XML_USE_OUTLINE_LEVEL, sal_True);
591 
592 		// use index marks
593 		ExportBoolean(rPropertySet, sCreateFromMarks,
594 					  XML_USE_INDEX_MARKS, sal_True);
595 
596 		// use level styles
597 		ExportBoolean(rPropertySet, sCreateFromLevelParagraphStyles,
598 					  XML_USE_INDEX_SOURCE_STYLES, sal_False);
599 
600 		ExportBaseIndexSource(TEXT_SECTION_TYPE_TOC, rPropertySet);
601 	}
602 
603 	ExportBaseIndexBody(TEXT_SECTION_TYPE_TOC, rPropertySet);
604 }
605 
ExportObjectIndexStart(const Reference<XPropertySet> & rPropertySet)606 void XMLSectionExport::ExportObjectIndexStart(
607 	const Reference<XPropertySet> & rPropertySet)
608 {
609 	// export index start
610 	ExportBaseIndexStart(XML_OBJECT_INDEX, rPropertySet);
611 
612 	// scope for index source element
613 	{
614 		ExportBoolean(rPropertySet, sCreateFromOtherEmbeddedObjects,
615 					  XML_USE_OTHER_OBJECTS, sal_False);
616 		ExportBoolean(rPropertySet, sCreateFromStarCalc,
617 					  XML_USE_SPREADSHEET_OBJECTS, sal_False);
618 		ExportBoolean(rPropertySet, sCreateFromStarChart,
619 					  XML_USE_CHART_OBJECTS, sal_False);
620 		ExportBoolean(rPropertySet, sCreateFromStarDraw,
621 					  XML_USE_DRAW_OBJECTS, sal_False);
622 		ExportBoolean(rPropertySet, sCreateFromStarMath,
623 					  XML_USE_MATH_OBJECTS, sal_False);
624 
625 		ExportBaseIndexSource(TEXT_SECTION_TYPE_OBJECT, rPropertySet);
626 	}
627 
628 	ExportBaseIndexBody(TEXT_SECTION_TYPE_OBJECT, rPropertySet);
629 }
630 
ExportIllustrationIndexStart(const Reference<XPropertySet> & rPropertySet)631 void XMLSectionExport::ExportIllustrationIndexStart(
632 	const Reference<XPropertySet> & rPropertySet)
633 {
634 	// export index start
635 	ExportBaseIndexStart(XML_ILLUSTRATION_INDEX, rPropertySet);
636 
637 	// scope for index source element
638 	{
639 		// export common attributes for illustration and table indices
640 		ExportTableAndIllustrationIndexSourceAttributes(rPropertySet);
641 
642 		ExportBaseIndexSource(TEXT_SECTION_TYPE_ILLUSTRATION, rPropertySet);
643 	}
644 
645 	ExportBaseIndexBody(TEXT_SECTION_TYPE_ILLUSTRATION, rPropertySet);
646 }
647 
ExportTableIndexStart(const Reference<XPropertySet> & rPropertySet)648 void XMLSectionExport::ExportTableIndexStart(
649 	const Reference<XPropertySet> & rPropertySet)
650 {
651 	// export index start
652 	ExportBaseIndexStart(XML_TABLE_INDEX, rPropertySet);
653 
654 	// scope for index source element
655 	{
656 		// export common attributes for illustration and table indices
657 		ExportTableAndIllustrationIndexSourceAttributes(rPropertySet);
658 
659 		ExportBaseIndexSource(TEXT_SECTION_TYPE_TABLE, rPropertySet);
660 	}
661 
662 	ExportBaseIndexBody(TEXT_SECTION_TYPE_TABLE, rPropertySet);
663 }
664 
ExportAlphabeticalIndexStart(const Reference<XPropertySet> & rPropertySet)665 void XMLSectionExport::ExportAlphabeticalIndexStart(
666 	const Reference<XPropertySet> & rPropertySet)
667 {
668 	// export TOC element start
669 	ExportBaseIndexStart(XML_ALPHABETICAL_INDEX, rPropertySet);
670 
671 	// scope for table-of-content-source element
672 	{
673 
674 		// style name (if present)
675 		Any aAny;
676 		aAny = rPropertySet->getPropertyValue(sMainEntryCharacterStyleName);
677 		OUString sStyleName;
678 		aAny >>= sStyleName;
679 		if (sStyleName.getLength())
680 		{
681 			GetExport().AddAttribute(XML_NAMESPACE_TEXT,
682 									 XML_MAIN_ENTRY_STYLE_NAME,
683 									 GetExport().EncodeStyleName( sStyleName ));
684 		}
685 
686 		// other (boolean) attributes
687 		ExportBoolean(rPropertySet, sIsCaseSensitive, XML_IGNORE_CASE,
688 					  sal_False, sal_True);
689 		ExportBoolean(rPropertySet, sUseAlphabeticalSeparators,
690 					  XML_ALPHABETICAL_SEPARATORS, sal_False);
691 		ExportBoolean(rPropertySet, sUseCombinedEntries, XML_COMBINE_ENTRIES,
692 					  sal_True);
693 		ExportBoolean(rPropertySet, sUseDash, XML_COMBINE_ENTRIES_WITH_DASH,
694 					  sal_False);
695 		ExportBoolean(rPropertySet, sUseKeyAsEntry, XML_USE_KEYS_AS_ENTRIES,
696 					  sal_False);
697 		ExportBoolean(rPropertySet, sUsePP, XML_COMBINE_ENTRIES_WITH_PP,
698 					  sal_True);
699 		ExportBoolean(rPropertySet, sUseUpperCase, XML_CAPITALIZE_ENTRIES,
700 					  sal_False);
701 		ExportBoolean(rPropertySet, sIsCommaSeparated, XML_COMMA_SEPARATED,
702 					  sal_False);
703 
704         // sort algorithm
705         aAny = rPropertySet->getPropertyValue(sSortAlgorithm);
706         OUString sAlgorithm;
707         aAny >>= sAlgorithm;
708         if (sAlgorithm.getLength() > 0)
709         {
710             GetExport().AddAttribute( XML_NAMESPACE_TEXT, XML_SORT_ALGORITHM,
711                                       sAlgorithm );
712         }
713 
714         // locale
715         aAny = rPropertySet->getPropertyValue(sLocale);
716         Locale aLocale;
717         aAny >>= aLocale;
718         GetExport().AddAttribute(XML_NAMESPACE_FO, XML_LANGUAGE,
719                                  aLocale.Language);
720         GetExport().AddAttribute(XML_NAMESPACE_FO, XML_COUNTRY,
721                                  aLocale.Country);
722 
723 		ExportBaseIndexSource(TEXT_SECTION_TYPE_ALPHABETICAL, rPropertySet);
724 	}
725 
726 	ExportBaseIndexBody(TEXT_SECTION_TYPE_ALPHABETICAL, rPropertySet);
727 }
728 
ExportUserIndexStart(const Reference<XPropertySet> & rPropertySet)729 void XMLSectionExport::ExportUserIndexStart(
730 	const Reference<XPropertySet> & rPropertySet)
731 {
732 	// export TOC element start
733 	ExportBaseIndexStart(XML_USER_INDEX, rPropertySet);
734 
735 	// scope for table-of-content-source element
736 	{
737 		// bool attributes
738 		ExportBoolean(rPropertySet, sCreateFromEmbeddedObjects,
739 					  XML_USE_OBJECTS, sal_False);
740 		ExportBoolean(rPropertySet, sCreateFromGraphicObjects,
741 					  XML_USE_GRAPHICS, sal_False);
742 		ExportBoolean(rPropertySet, sCreateFromMarks,
743 					  XML_USE_INDEX_MARKS, sal_False);
744 		ExportBoolean(rPropertySet, sCreateFromTables,
745 					  XML_USE_TABLES, sal_False);
746 		ExportBoolean(rPropertySet, sCreateFromTextFrames,
747 					  XML_USE_FLOATING_FRAMES, sal_False);
748 		ExportBoolean(rPropertySet, sUseLevelFromSource,
749 					  XML_COPY_OUTLINE_LEVELS, sal_False);
750 		ExportBoolean(rPropertySet, sCreateFromLevelParagraphStyles,
751 					  XML_USE_INDEX_SOURCE_STYLES, sal_False);
752 
753         Any aAny = rPropertySet->getPropertyValue( sUserIndexName );
754         OUString sIndexName;
755         aAny >>= sIndexName;
756         GetExport().AddAttribute(XML_NAMESPACE_TEXT, XML_INDEX_NAME,
757                                  sIndexName);
758 
759 		ExportBaseIndexSource(TEXT_SECTION_TYPE_USER, rPropertySet);
760 	}
761 
762 	ExportBaseIndexBody(TEXT_SECTION_TYPE_USER, rPropertySet);
763 }
764 
ExportBibliographyStart(const Reference<XPropertySet> & rPropertySet)765 void XMLSectionExport::ExportBibliographyStart(
766 	const Reference<XPropertySet> & rPropertySet)
767 {
768 	// export TOC element start
769 	ExportBaseIndexStart(XML_BIBLIOGRAPHY, rPropertySet);
770 
771 	// scope for table-of-content-source element
772 	{
773 		// No attributes. Fine.
774 
775 		ExportBaseIndexSource(TEXT_SECTION_TYPE_BIBLIOGRAPHY, rPropertySet);
776 	}
777 
778 	ExportBaseIndexBody(TEXT_SECTION_TYPE_BIBLIOGRAPHY, rPropertySet);
779 }
780 
781 
ExportBaseIndexStart(XMLTokenEnum eElement,const Reference<XPropertySet> & rPropertySet)782 void XMLSectionExport::ExportBaseIndexStart(
783     XMLTokenEnum eElement,
784 	const Reference<XPropertySet> & rPropertySet)
785 {
786 	// protect + protection key
787 	Any aAny = rPropertySet->getPropertyValue(sIsProtected);
788 	if (*(sal_Bool*)aAny.getValue())
789 	{
790 		GetExport().AddAttribute(XML_NAMESPACE_TEXT, XML_PROTECTED, XML_TRUE);
791 	}
792 
793     // index name
794     OUString sIndexName;
795     rPropertySet->getPropertyValue(sName) >>= sIndexName;
796     if ( sIndexName.getLength() > 0 )
797     {
798         GetExport().AddAttribute(XML_NAMESPACE_TEXT, XML_NAME, sIndexName);
799     }
800 
801 	// index  Element start
802 	GetExport().IgnorableWhitespace();
803 	GetExport().StartElement( XML_NAMESPACE_TEXT, eElement, sal_False );
804 }
805 
806 static const XMLTokenEnum aTypeSourceElementNameMap[] =
807 {
808 	XML_TABLE_OF_CONTENT_SOURCE,		// TOC
809 	XML_TABLE_INDEX_SOURCE,			// table index
810 	XML_ILLUSTRATION_INDEX_SOURCE,		// illustration index
811 	XML_OBJECT_INDEX_SOURCE,			// object index
812 	XML_USER_INDEX_SOURCE,				// user index
813 	XML_ALPHABETICAL_INDEX_SOURCE,		// alphabetical index
814 	XML_BIBLIOGRAPHY_SOURCE			// bibliography
815 };
816 
ExportBaseIndexSource(SectionTypeEnum eType,const Reference<XPropertySet> & rPropertySet)817 void XMLSectionExport::ExportBaseIndexSource(
818 	SectionTypeEnum eType,
819 	const Reference<XPropertySet> & rPropertySet)
820 {
821 	// check type
822 	OSL_ENSURE(eType >= TEXT_SECTION_TYPE_TOC, "illegal index type");
823 	OSL_ENSURE(eType <= TEXT_SECTION_TYPE_BIBLIOGRAPHY, "illegal index type");
824 
825 	Any aAny;
826 
827 	// common attributes; not supported by bibliography
828 	if (eType != TEXT_SECTION_TYPE_BIBLIOGRAPHY)
829 	{
830 		// document or chapter index?
831 		aAny = rPropertySet->getPropertyValue(sCreateFromChapter);
832 		if (*(sal_Bool*)aAny.getValue())
833 		{
834 			GetExport().AddAttribute(XML_NAMESPACE_TEXT,
835                                      XML_INDEX_SCOPE, XML_CHAPTER);
836 		}
837 
838 		// tab-stops relative to margin?
839 		aAny = rPropertySet->getPropertyValue(sIsRelativeTabstops);
840 		if (! *(sal_Bool*)aAny.getValue())
841 		{
842 			GetExport().AddAttribute(XML_NAMESPACE_TEXT,
843                                      XML_RELATIVE_TAB_STOP_POSITION,
844                                      XML_FALSE);
845 		}
846     }
847 
848 	// the index source element (all indices)
849 	SvXMLElementExport aElem(GetExport(),
850 							 XML_NAMESPACE_TEXT,
851 							 GetXMLToken(
852                                  aTypeSourceElementNameMap[
853                                     eType - TEXT_SECTION_TYPE_TOC]),
854 							 sal_True, sal_True);
855 
856 	// scope for title template (all indices)
857 	{
858 		// header style name
859 		aAny = rPropertySet->getPropertyValue(sParaStyleHeading);
860 		OUString sStyleName;
861 		aAny >>= sStyleName;
862 		GetExport().AddAttribute(XML_NAMESPACE_TEXT,
863 								 XML_STYLE_NAME,
864 								 GetExport().EncodeStyleName( sStyleName ));
865 
866 		// title template
867 		SvXMLElementExport aHeaderTemplate(GetExport(),
868 										   XML_NAMESPACE_TEXT,
869 										   XML_INDEX_TITLE_TEMPLATE,
870 										   sal_True, sal_False);
871 
872 		// title as element content
873 		aAny = rPropertySet->getPropertyValue(sTitle);
874 		OUString sTitleString;
875 		aAny >>= sTitleString;
876 		GetExport().Characters(sTitleString);
877 	}
878 
879 	// export level templates (all indices)
880 	aAny = rPropertySet->getPropertyValue(sLevelFormat);
881 	Reference<XIndexReplace> xLevelTemplates;
882 	aAny >>= xLevelTemplates;
883 
884 	// iterate over level formats;
885 	// skip element 0 (empty template for title)
886 	sal_Int32 nLevelCount = xLevelTemplates->getCount();
887 	for(sal_Int32 i = 1; i<nLevelCount; i++)
888 	{
889 		// get sequence
890 		Sequence<PropertyValues> aTemplateSequence;
891 		aAny = xLevelTemplates->getByIndex(i);
892 		aAny >>= aTemplateSequence;
893 
894 		// export the sequence (abort export if an error occured; #91214#)
895 		sal_Bool bResult =
896             ExportIndexTemplate(eType, i, rPropertySet, aTemplateSequence);
897         if ( !bResult )
898             break;
899 	}
900 
901 	// only TOC and user index:
902 	// styles from which to build the index (LevelParagraphStyles)
903 	if ( (TEXT_SECTION_TYPE_TOC == eType) ||
904 		 (TEXT_SECTION_TYPE_USER == eType)   )
905 	{
906 		aAny = rPropertySet->getPropertyValue(sLevelParagraphStyles);
907 		Reference<XIndexReplace> xLevelParagraphStyles;
908 		aAny >>= xLevelParagraphStyles;
909 		ExportLevelParagraphStyles(xLevelParagraphStyles);
910 	}
911 }
912 
913 
ExportBaseIndexBody(SectionTypeEnum eType,const Reference<XPropertySet> &)914 void XMLSectionExport::ExportBaseIndexBody(
915 	SectionTypeEnum
916     #if OSL_DEBUG_LEVEL > 0
917     eType
918     #endif
919     ,
920 	const Reference<XPropertySet> &)
921 {
922 	// type not used; checked anyway.
923 	OSL_ENSURE(eType >= TEXT_SECTION_TYPE_TOC, "illegal index type");
924 	OSL_ENSURE(eType <= TEXT_SECTION_TYPE_BIBLIOGRAPHY, "illegal index type");
925 
926 	// export start only
927 
928 	// any old attributes?
929 	GetExport().CheckAttrList();
930 
931 	// start surrounded by whitespace
932 	GetExport().IgnorableWhitespace();
933 	GetExport().StartElement( XML_NAMESPACE_TEXT, XML_INDEX_BODY, sal_True );
934 }
935 
ExportTableAndIllustrationIndexSourceAttributes(const Reference<XPropertySet> & rPropertySet)936 void XMLSectionExport::ExportTableAndIllustrationIndexSourceAttributes(
937 	const Reference<XPropertySet> & rPropertySet)
938 {
939 	// use caption
940 	Any aAny = rPropertySet->getPropertyValue(sCreateFromLabels);
941 	if (! *(sal_Bool*)aAny.getValue())
942 	{
943 		GetExport().AddAttribute(XML_NAMESPACE_TEXT,
944                                  XML_USE_CAPTION, XML_FALSE);
945 	}
946 
947 	// sequence name
948 	aAny = rPropertySet->getPropertyValue(sLabelCategory);
949 	OUString sSequenceName;
950 	aAny >>= sSequenceName;
951 	GetExport().AddAttribute(XML_NAMESPACE_TEXT,
952 							 XML_CAPTION_SEQUENCE_NAME,
953 							 sSequenceName);
954 
955 	// caption format
956 	aAny = rPropertySet->getPropertyValue(sLabelDisplayType);
957 	sal_Int16 nType = 0;
958 	aAny >>= nType;
959 	GetExport().AddAttribute(XML_NAMESPACE_TEXT,
960                              XML_CAPTION_SEQUENCE_FORMAT,
961                              XMLTextFieldExport::MapReferenceType(nType));
962 }
963 
964 
965 // map index of LevelFormats to attribute value;
966 // level 0 is always the header
967 static const XMLTokenEnum aLevelNameTOCMap[] =
968 	{ XML_TOKEN_INVALID, XML_1, XML_2, XML_3, XML_4, XML_5, XML_6, XML_7,
969 		  XML_8, XML_9, XML_10, XML_TOKEN_INVALID };
970 static const XMLTokenEnum aLevelNameTableMap[] =
971 	{ XML_TOKEN_INVALID, XML__EMPTY, XML_TOKEN_INVALID };
972 static const XMLTokenEnum aLevelNameAlphaMap[] =
973 	{ XML_TOKEN_INVALID, XML_SEPARATOR, XML_1, XML_2, XML_3, XML_TOKEN_INVALID };
974 static const XMLTokenEnum aLevelNameBibliographyMap[] =
975 	{ XML_TOKEN_INVALID, XML_ARTICLE, XML_BOOK, XML_BOOKLET, XML_CONFERENCE,
976 		  XML_CUSTOM1, XML_CUSTOM2, XML_CUSTOM3, XML_CUSTOM4,
977 		  XML_CUSTOM5, XML_EMAIL, XML_INBOOK, XML_INCOLLECTION,
978 		  XML_INPROCEEDINGS, XML_JOURNAL,
979 		  XML_MANUAL, XML_MASTERSTHESIS, XML_MISC, XML_PHDTHESIS,
980 		  XML_PROCEEDINGS, XML_TECHREPORT, XML_UNPUBLISHED, XML_WWW,
981 		  XML_TOKEN_INVALID };
982 
983 static const XMLTokenEnum* aTypeLevelNameMap[] =
984 {
985 	aLevelNameTOCMap,			// TOC
986 	aLevelNameTableMap,			// table index
987 	aLevelNameTableMap,			// illustration index
988 	aLevelNameTableMap,			// object index
989 	aLevelNameTOCMap,			// user index
990 	aLevelNameAlphaMap,			// alphabetical index
991 	aLevelNameBibliographyMap	// bibliography
992 };
993 
994 static const sal_Char* aLevelStylePropNameTOCMap[] =
995 	{ NULL, "ParaStyleLevel1", "ParaStyleLevel2", "ParaStyleLevel3",
996 		  "ParaStyleLevel4", "ParaStyleLevel5", "ParaStyleLevel6",
997 		  "ParaStyleLevel7", "ParaStyleLevel8", "ParaStyleLevel9",
998 		  "ParaStyleLevel10", NULL };
999 static const sal_Char* aLevelStylePropNameTableMap[] =
1000 	{ NULL, "ParaStyleLevel1", NULL };
1001 static const sal_Char* aLevelStylePropNameAlphaMap[] =
1002 	{ NULL, "ParaStyleSeparator", "ParaStyleLevel1", "ParaStyleLevel2",
1003 		  "ParaStyleLevel3", NULL };
1004 static const sal_Char* aLevelStylePropNameBibliographyMap[] =
1005 		  // TODO: replace with real property names, when available
1006 	{ NULL, "ParaStyleLevel1", "ParaStyleLevel1", "ParaStyleLevel1",
1007 		  "ParaStyleLevel1", "ParaStyleLevel1", "ParaStyleLevel1",
1008 		  "ParaStyleLevel1", "ParaStyleLevel1", "ParaStyleLevel1",
1009 		  "ParaStyleLevel1", "ParaStyleLevel1", "ParaStyleLevel1",
1010 		  "ParaStyleLevel1", "ParaStyleLevel1", "ParaStyleLevel1",
1011 		  "ParaStyleLevel1", "ParaStyleLevel1", "ParaStyleLevel1",
1012 		  "ParaStyleLevel1", "ParaStyleLevel1", "ParaStyleLevel1",
1013 		  "ParaStyleLevel1",
1014 		  NULL };
1015 
1016 static const sal_Char** aTypeLevelStylePropNameMap[] =
1017 {
1018 	aLevelStylePropNameTOCMap,			// TOC
1019 	aLevelStylePropNameTableMap,		// table index
1020 	aLevelStylePropNameTableMap,		// illustration index
1021 	aLevelStylePropNameTableMap,		// object index
1022 	aLevelStylePropNameTOCMap,			// user index
1023 	aLevelStylePropNameAlphaMap,		// alphabetical index
1024 	aLevelStylePropNameBibliographyMap	// bibliography
1025 };
1026 
1027 static const XMLTokenEnum aTypeLevelAttrMap[] =
1028 {
1029 	XML_OUTLINE_LEVEL,		// TOC
1030 	XML_TOKEN_INVALID,		// table index
1031 	XML_TOKEN_INVALID,		// illustration index
1032 	XML_TOKEN_INVALID,		// object index
1033 	XML_OUTLINE_LEVEL,		// user index
1034 	XML_OUTLINE_LEVEL,		// alphabetical index
1035 	XML_BIBLIOGRAPHY_TYPE	// bibliography
1036 };
1037 
1038 static const XMLTokenEnum aTypeElementNameMap[] =
1039 {
1040 	XML_TABLE_OF_CONTENT_ENTRY_TEMPLATE,	// TOC
1041 	XML_TABLE_INDEX_ENTRY_TEMPLATE,		// table index
1042 	XML_ILLUSTRATION_INDEX_ENTRY_TEMPLATE,	// illustration index
1043 	XML_OBJECT_INDEX_ENTRY_TEMPLATE,		// object index
1044 	XML_USER_INDEX_ENTRY_TEMPLATE,			// user index
1045 	XML_ALPHABETICAL_INDEX_ENTRY_TEMPLATE,	// alphabetical index
1046 	XML_BIBLIOGRAPHY_ENTRY_TEMPLATE		// bibliography
1047 };
1048 
1049 
ExportIndexTemplate(SectionTypeEnum eType,sal_Int32 nOutlineLevel,const Reference<XPropertySet> & rPropertySet,Sequence<Sequence<PropertyValue>> & rValues)1050 sal_Bool XMLSectionExport::ExportIndexTemplate(
1051 	SectionTypeEnum eType,
1052 	sal_Int32 nOutlineLevel,
1053 	const Reference<XPropertySet> & rPropertySet,
1054 	Sequence<Sequence<PropertyValue> > & rValues)
1055 {
1056 	OSL_ENSURE(eType >= TEXT_SECTION_TYPE_TOC, "illegal index type");
1057 	OSL_ENSURE(eType <= TEXT_SECTION_TYPE_BIBLIOGRAPHY, "illegal index type");
1058 	OSL_ENSURE(nOutlineLevel >= 0, "illegal outline level");
1059 
1060 	if ( (eType >= TEXT_SECTION_TYPE_TOC) &&
1061 		 (eType <= TEXT_SECTION_TYPE_BIBLIOGRAPHY) &&
1062 		 (nOutlineLevel >= 0) )
1063 	{
1064 		// get level name and level attribute name from aLevelNameMap;
1065 		const XMLTokenEnum eLevelAttrName(
1066 			aTypeLevelAttrMap[eType-TEXT_SECTION_TYPE_TOC]);
1067 		const XMLTokenEnum eLevelName(
1068 			aTypeLevelNameMap[eType-TEXT_SECTION_TYPE_TOC][nOutlineLevel]);
1069 
1070         // #92124#: some old documents may be broken, then they have
1071         // too many template levels; we need to recognize this and
1072         // export only as many as is legal for the respective index
1073         // type. To do this, we simply return an error flag, which
1074         // will then abort further template level exports.
1075 		OSL_ENSURE(XML_TOKEN_INVALID != eLevelName, "can't find level name");
1076         if ( XML_TOKEN_INVALID == eLevelName )
1077         {
1078             // output level not found? Then end of templates! #91214#
1079             return sal_False;
1080         }
1081 
1082 		// output level name
1083 		if ((XML_TOKEN_INVALID != eLevelName) && (XML_TOKEN_INVALID != eLevelAttrName))
1084 		{
1085 			GetExport().AddAttribute(XML_NAMESPACE_TEXT,
1086 										  GetXMLToken(eLevelAttrName),
1087 										  GetXMLToken(eLevelName));
1088 		}
1089 
1090 		// paragraph level style name
1091 		const sal_Char* pPropName(
1092 			aTypeLevelStylePropNameMap[eType-TEXT_SECTION_TYPE_TOC][nOutlineLevel]);
1093 		OSL_ENSURE(NULL != pPropName, "can't find property name");
1094 		if (NULL != pPropName)
1095 		{
1096 			Any aAny = rPropertySet->getPropertyValue(
1097 				OUString::createFromAscii(pPropName));
1098 			OUString sParaStyleName;
1099 			aAny >>= sParaStyleName;
1100 			GetExport().AddAttribute(XML_NAMESPACE_TEXT,
1101 									 XML_STYLE_NAME,
1102 									 GetExport().EncodeStyleName( sParaStyleName ));
1103 		}
1104 
1105 		// template element
1106 		const XMLTokenEnum eElementName(
1107 			aTypeElementNameMap[eType - TEXT_SECTION_TYPE_TOC]);
1108 		SvXMLElementExport aLevelTemplate(GetExport(),
1109 										  XML_NAMESPACE_TEXT,
1110 										  GetXMLToken(eElementName),
1111 										  sal_True, sal_True);
1112 
1113 		// export sequence
1114 		sal_Int32 nTemplateCount = rValues.getLength();
1115 		for(sal_Int32 nTemplateNo = 0;
1116 			nTemplateNo < nTemplateCount;
1117 			nTemplateNo++)
1118 		{
1119 			ExportIndexTemplateElement(
1120                 eType,  //i90246
1121 				rValues[nTemplateNo]);
1122 		}
1123 	}
1124 
1125     return sal_True;
1126 }
1127 
1128 
1129 enum TemplateTypeEnum
1130 {
1131 	TOK_TTYPE_ENTRY_NUMBER,
1132 	TOK_TTYPE_ENTRY_TEXT,
1133 	TOK_TTYPE_TAB_STOP,
1134 	TOK_TTYPE_TEXT,
1135 	TOK_TTYPE_PAGE_NUMBER,
1136 	TOK_TTYPE_CHAPTER_INFO,
1137 	TOK_TTYPE_HYPERLINK_START,
1138 	TOK_TTYPE_HYPERLINK_END,
1139 	TOK_TTYPE_BIBLIOGRAPHY,
1140 	TOK_TTYPE_INVALID
1141 };
1142 
1143 enum TemplateParamEnum
1144 {
1145 	TOK_TPARAM_TOKEN_TYPE,
1146 	TOK_TPARAM_CHAR_STYLE,
1147 	TOK_TPARAM_TAB_RIGHT_ALIGNED,
1148 	TOK_TPARAM_TAB_POSITION,
1149 	TOK_TPARAM_TAB_WITH_TAB, // #i21237#
1150 	TOK_TPARAM_TAB_FILL_CHAR,
1151 	TOK_TPARAM_TEXT,
1152 	TOK_TPARAM_CHAPTER_FORMAT,
1153 	TOK_TPARAM_CHAPTER_LEVEL,//i53420
1154 	TOK_TPARAM_BIBLIOGRAPHY_DATA
1155 };
1156 
1157 SvXMLEnumStringMapEntry __READONLY_DATA aTemplateTypeMap[] =
1158 {
1159 	ENUM_STRING_MAP_ENTRY( "TokenEntryNumber",  TOK_TTYPE_ENTRY_NUMBER ),
1160     ENUM_STRING_MAP_ENTRY( "TokenEntryText",    TOK_TTYPE_ENTRY_TEXT ),
1161     ENUM_STRING_MAP_ENTRY( "TokenTabStop",      TOK_TTYPE_TAB_STOP ),
1162     ENUM_STRING_MAP_ENTRY( "TokenText",         TOK_TTYPE_TEXT ),
1163 	ENUM_STRING_MAP_ENTRY( "TokenPageNumber",   TOK_TTYPE_PAGE_NUMBER ),
1164 	ENUM_STRING_MAP_ENTRY( "TokenChapterInfo",  TOK_TTYPE_CHAPTER_INFO ),
1165     ENUM_STRING_MAP_ENTRY( "TokenHyperlinkStart", TOK_TTYPE_HYPERLINK_START ),
1166 	ENUM_STRING_MAP_ENTRY( "TokenHyperlinkEnd",	TOK_TTYPE_HYPERLINK_END ),
1167 	ENUM_STRING_MAP_ENTRY( "TokenBibliographyDataField", TOK_TTYPE_BIBLIOGRAPHY ),
1168     ENUM_STRING_MAP_END()
1169 };
1170 
1171 SvXMLEnumStringMapEntry __READONLY_DATA aTemplateParamMap[] =
1172 {
1173 	ENUM_STRING_MAP_ENTRY( "TokenType",             TOK_TPARAM_TOKEN_TYPE ),
1174 	ENUM_STRING_MAP_ENTRY( "CharacterStyleName",    TOK_TPARAM_CHAR_STYLE ),
1175 	ENUM_STRING_MAP_ENTRY( "TabStopRightAligned",   TOK_TPARAM_TAB_RIGHT_ALIGNED ),
1176 	ENUM_STRING_MAP_ENTRY( "TabStopPosition",       TOK_TPARAM_TAB_POSITION ),
1177 	ENUM_STRING_MAP_ENTRY( "TabStopFillCharacter",  TOK_TPARAM_TAB_FILL_CHAR ),
1178     // #i21237#
1179 	ENUM_STRING_MAP_ENTRY( "WithTab",               TOK_TPARAM_TAB_WITH_TAB ),
1180 	ENUM_STRING_MAP_ENTRY( "Text",                  TOK_TPARAM_TEXT ),
1181 	ENUM_STRING_MAP_ENTRY( "ChapterFormat",         TOK_TPARAM_CHAPTER_FORMAT ),
1182 	ENUM_STRING_MAP_ENTRY( "ChapterLevel",          TOK_TPARAM_CHAPTER_LEVEL ),//i53420
1183 	ENUM_STRING_MAP_ENTRY( "BibliographyDataField", TOK_TPARAM_BIBLIOGRAPHY_DATA ),
1184     ENUM_STRING_MAP_END()
1185 };
1186 
1187 SvXMLEnumMapEntry __READONLY_DATA aBibliographyDataFieldMap[] =
1188 {
1189 	{ XML_ADDRESS,				BibliographyDataField::ADDRESS },
1190 	{ XML_ANNOTE,				BibliographyDataField::ANNOTE },
1191 	{ XML_AUTHOR,				BibliographyDataField::AUTHOR },
1192 	{ XML_BIBLIOGRAPHY_TYPE,    BibliographyDataField::BIBILIOGRAPHIC_TYPE },
1193 	{ XML_BOOKTITLE,			BibliographyDataField::BOOKTITLE },
1194 	{ XML_CHAPTER,				BibliographyDataField::CHAPTER },
1195 	{ XML_CUSTOM1,				BibliographyDataField::CUSTOM1 },
1196 	{ XML_CUSTOM2,				BibliographyDataField::CUSTOM2 },
1197 	{ XML_CUSTOM3,				BibliographyDataField::CUSTOM3 },
1198 	{ XML_CUSTOM4,				BibliographyDataField::CUSTOM4 },
1199 	{ XML_CUSTOM5,				BibliographyDataField::CUSTOM5 },
1200 	{ XML_EDITION,				BibliographyDataField::EDITION },
1201 	{ XML_EDITOR,				BibliographyDataField::EDITOR },
1202 	{ XML_HOWPUBLISHED,		    BibliographyDataField::HOWPUBLISHED },
1203 	{ XML_IDENTIFIER,			BibliographyDataField::IDENTIFIER },
1204 	{ XML_INSTITUTION,			BibliographyDataField::INSTITUTION },
1205 	{ XML_ISBN,				    BibliographyDataField::ISBN },
1206 	{ XML_JOURNAL,				BibliographyDataField::JOURNAL },
1207 	{ XML_MONTH,				BibliographyDataField::MONTH },
1208 	{ XML_NOTE,				    BibliographyDataField::NOTE },
1209 	{ XML_NUMBER,				BibliographyDataField::NUMBER },
1210 	{ XML_ORGANIZATIONS,		BibliographyDataField::ORGANIZATIONS },
1211 	{ XML_PAGES,				BibliographyDataField::PAGES },
1212 	{ XML_PUBLISHER,			BibliographyDataField::PUBLISHER },
1213 	{ XML_REPORT_TYPE,			BibliographyDataField::REPORT_TYPE },
1214 	{ XML_SCHOOL,				BibliographyDataField::SCHOOL },
1215     { XML_SERIES,				BibliographyDataField::SERIES },
1216 	{ XML_TITLE,				BibliographyDataField::TITLE },
1217 	{ XML_URL,					BibliographyDataField::URL },
1218 	{ XML_VOLUME,				BibliographyDataField::VOLUME },
1219 	{ XML_YEAR,				    BibliographyDataField::YEAR },
1220 	{ XML_TOKEN_INVALID, 0 }
1221 };
1222 
ExportIndexTemplateElement(SectionTypeEnum eType,Sequence<PropertyValue> & rValues)1223 void XMLSectionExport::ExportIndexTemplateElement(
1224     SectionTypeEnum eType,  //i90246
1225     Sequence<PropertyValue> & rValues)
1226 {
1227 	// variables for template values
1228 
1229 	// char style
1230 	OUString sCharStyle;
1231 	sal_Bool bCharStyleOK = sal_False;
1232 
1233 	// text
1234 	OUString sText;
1235 	sal_Bool bTextOK = sal_False;
1236 
1237 	// tab position
1238 	sal_Bool bRightAligned = sal_False;
1239 	sal_Bool bRightAlignedOK = sal_False;
1240 
1241 	// tab position
1242 	sal_Int32 nTabPosition = 0;
1243 	sal_Bool bTabPositionOK = sal_False;
1244 
1245 	// fill character
1246 	OUString sFillChar;
1247 	sal_Bool bFillCharOK = sal_False;
1248 
1249 	// chapter format
1250 	sal_Int16 nChapterFormat = 0;
1251 	sal_Bool bChapterFormatOK = sal_False;
1252 
1253     // outline max level
1254 	sal_Int16 nLevel = 0;
1255 	sal_Bool bLevelOK = sal_False;
1256 
1257 	// Bibliography Data
1258 	sal_Int16 nBibliographyData = 0;
1259 	sal_Bool bBibliographyDataOK = sal_False;
1260 
1261     // With Tab Stop #i21237#
1262     sal_Bool bWithTabStop = sal_False;
1263     sal_Bool bWithTabStopOK = sal_False;
1264 
1265     //i90246, the ODF version being written to is:
1266     const SvtSaveOptions::ODFDefaultVersion aODFVersion = rExport.getDefaultVersion();
1267     //the above version cannot be used for old OOo (OOo 1.0) formats!
1268 
1269     // token type
1270 	enum TemplateTypeEnum nTokenType = TOK_TTYPE_INVALID;
1271 
1272 	sal_Int32 nCount = rValues.getLength();
1273 	for(sal_Int32 i = 0; i<nCount; i++)
1274 	{
1275 		sal_uInt16 nToken;
1276 		if ( SvXMLUnitConverter::convertEnum( nToken, rValues[i].Name,
1277 											  aTemplateParamMap ) )
1278 		{
1279 			// Only use direct and default values.
1280 			// Wrong. no property states, so ignore.
1281 			// if ( (beans::PropertyState_DIRECT_VALUE == rValues[i].State) ||
1282 			//      (beans::PropertyState_DEFAULT_VALUE == rValues[i].State)  )
1283 
1284 			switch (nToken)
1285 			{
1286 				case TOK_TPARAM_TOKEN_TYPE:
1287 				{
1288 					sal_uInt16 nTmp;
1289 					OUString sVal;
1290 					rValues[i].Value >>= sVal;
1291 					if (SvXMLUnitConverter::convertEnum( nTmp, sVal,
1292 														 aTemplateTypeMap))
1293 					{
1294 						nTokenType = (enum TemplateTypeEnum)nTmp;
1295 					}
1296 					break;
1297 				}
1298 
1299 				case TOK_TPARAM_CHAR_STYLE:
1300 					// only valid, if not empty
1301 					rValues[i].Value >>= sCharStyle;
1302 					bCharStyleOK = sCharStyle.getLength() > 0;
1303 					break;
1304 
1305 				case TOK_TPARAM_TEXT:
1306 					rValues[i].Value >>= sText;
1307 					bTextOK = sal_True;
1308 					break;
1309 
1310 				case TOK_TPARAM_TAB_RIGHT_ALIGNED:
1311 					bRightAligned =
1312 						*(sal_Bool *)rValues[i].Value.getValue();
1313 					bRightAlignedOK = sal_True;
1314 					break;
1315 
1316 				case TOK_TPARAM_TAB_POSITION:
1317 					rValues[i].Value >>= nTabPosition;
1318 					bTabPositionOK = sal_True;
1319 					break;
1320 
1321                 // #i21237#
1322                 case TOK_TPARAM_TAB_WITH_TAB:
1323 					bWithTabStop = *(sal_Bool *)rValues[i].Value.getValue();
1324 					bWithTabStopOK = sal_True;
1325 					break;
1326 
1327 				case TOK_TPARAM_TAB_FILL_CHAR:
1328 					rValues[i].Value >>= sFillChar;
1329 					bFillCharOK = sal_True;
1330 					break;
1331 
1332 				case TOK_TPARAM_CHAPTER_FORMAT:
1333 					rValues[i].Value >>= nChapterFormat;
1334 					bChapterFormatOK = sal_True;
1335 					break;
1336 //---> i53420
1337                 case TOK_TPARAM_CHAPTER_LEVEL:
1338                     rValues[i].Value >>= nLevel;
1339                     bLevelOK = sal_True;
1340                     break;
1341 //<---
1342 				case TOK_TPARAM_BIBLIOGRAPHY_DATA:
1343 					rValues[i].Value >>= nBibliographyData;
1344 					bBibliographyDataOK = sal_True;
1345 					break;
1346 			}
1347 		}
1348 	}
1349 
1350 	// convert type to token (and check validity) ...
1351 	XMLTokenEnum eElement(XML_TOKEN_INVALID);
1352 	switch(nTokenType)
1353 	{
1354 		case TOK_TTYPE_ENTRY_TEXT:
1355 			eElement = XML_INDEX_ENTRY_TEXT;
1356 			break;
1357 		case TOK_TTYPE_TAB_STOP:
1358 			// test validity
1359 			if ( bRightAligned || bTabPositionOK || bFillCharOK )
1360             {
1361 				eElement = XML_INDEX_ENTRY_TAB_STOP;
1362             }
1363 			break;
1364 		case TOK_TTYPE_TEXT:
1365 			// test validity
1366 			if (bTextOK)
1367             {
1368                 eElement = XML_INDEX_ENTRY_SPAN;
1369             }
1370 			break;
1371 		case TOK_TTYPE_PAGE_NUMBER:
1372 			eElement = XML_INDEX_ENTRY_PAGE_NUMBER;
1373 			break;
1374 		case TOK_TTYPE_CHAPTER_INFO:	// keyword index
1375 			eElement = XML_INDEX_ENTRY_CHAPTER;
1376 			break;
1377 		case TOK_TTYPE_ENTRY_NUMBER:	// table of content
1378 			eElement = XML_INDEX_ENTRY_CHAPTER;
1379 			break;
1380 		case TOK_TTYPE_HYPERLINK_START:
1381 			eElement = XML_INDEX_ENTRY_LINK_START;
1382 			break;
1383 		case TOK_TTYPE_HYPERLINK_END:
1384 			eElement = XML_INDEX_ENTRY_LINK_END;
1385 			break;
1386 		case TOK_TTYPE_BIBLIOGRAPHY:
1387 			if (bBibliographyDataOK)
1388             {
1389 				eElement = XML_INDEX_ENTRY_BIBLIOGRAPHY;
1390             }
1391 			break;
1392 		default:
1393 			; // unknown/unimplemented template
1394 			break;
1395 	}
1396 
1397     //--->i90246
1398     //check the ODF version being exported
1399     if( aODFVersion == SvtSaveOptions::ODFVER_011
1400         || aODFVersion == SvtSaveOptions::ODFVER_010)
1401     {
1402         bLevelOK = sal_False;
1403         if (TOK_TTYPE_CHAPTER_INFO == nTokenType)
1404         {
1405             //if we are emitting for ODF 1.1 or 1.0, this information can be used for alphabetical index only
1406             //it's not permitted in other indexes
1407             if (eType != TEXT_SECTION_TYPE_ALPHABETICAL)
1408             {
1409                 eElement = XML_TOKEN_INVALID; //not permitted, invalidate the element
1410             }
1411             else //maps format for 1.1 & 1.0
1412             {
1413                 // a few word here: OOo up to 2.4 uses the field chapter info in Alphabetical index
1414                 // in a way different from the ODF 1.1/1.0 specification:
1415                 //
1416                 // ODF1.1/1.0         OOo display in chapter info                       ODF1.2
1417                 //                    (used in alphabetical index only
1418                 //
1419                 // number             chapter number without pre/postfix                plain-number
1420                 // number-and-name    chapter number without pre/postfix plus title     plain-number-and-name
1421                 //
1422                 // with issue i89791 the reading of ODF 1.1 and 1.0 was corrected
1423                 // this one corrects the writing back from ODF 1.2 to ODF 1.1/1.0
1424                 // unfortunately if there is another application which interprets correctly ODF1.1/1.0,
1425                 // the resulting alphabetical index will be rendered wrong by OOo 2.4 version
1426                 //
1427                 switch( nChapterFormat )
1428                 {
1429                 case ChapterFormat::DIGIT:
1430                     nChapterFormat = ChapterFormat::NUMBER;
1431                     break;
1432                 case ChapterFormat::NO_PREFIX_SUFFIX:
1433                     nChapterFormat = ChapterFormat::NAME_NUMBER;
1434                     break;
1435                 }
1436             }
1437         }
1438         else if (TOK_TTYPE_ENTRY_NUMBER == nTokenType)
1439         {
1440             //in case of ODF 1.1 or 1.0 the only allowed number format is "number"
1441             //so, force it...
1442             // The only expected 'foreign' nChapterFormat is
1443             // ' ChapterFormat::DIGIT', forced to 'none, since the
1444             // 'value allowed in ODF 1.1 and 1.0 is 'number' the default
1445             // this can be obtained by simply disabling the chapter format
1446             bChapterFormatOK = sal_False;
1447         }
1448     }
1449 //<---
1450 
1451     // ... and write Element
1452 	if (eElement != XML_TOKEN_INVALID)
1453 	{
1454 		// character style (for most templates)
1455 		if (bCharStyleOK)
1456 		{
1457 			switch (nTokenType)
1458 			{
1459 				case TOK_TTYPE_ENTRY_TEXT:
1460 				case TOK_TTYPE_TEXT:
1461 				case TOK_TTYPE_PAGE_NUMBER:
1462 				case TOK_TTYPE_ENTRY_NUMBER:
1463 				case TOK_TTYPE_HYPERLINK_START:
1464 				case TOK_TTYPE_HYPERLINK_END:
1465 				case TOK_TTYPE_BIBLIOGRAPHY:
1466                 case TOK_TTYPE_CHAPTER_INFO:
1467                 case TOK_TTYPE_TAB_STOP:
1468 					GetExport().AddAttribute(XML_NAMESPACE_TEXT,
1469 											 XML_STYLE_NAME,
1470 								 GetExport().EncodeStyleName( sCharStyle) );
1471 					break;
1472 				default:
1473 					; // nothing: no character style
1474 					break;
1475 			}
1476 		}
1477 
1478 		// tab properties
1479 		if (TOK_TTYPE_TAB_STOP == nTokenType)
1480 		{
1481 			// tab type
1482 			GetExport().AddAttribute(XML_NAMESPACE_STYLE, XML_TYPE,
1483                                      bRightAligned ? XML_RIGHT : XML_LEFT);
1484 
1485 			if (bTabPositionOK && (! bRightAligned))
1486 			{
1487 				// position for left tabs (convert to measure)
1488 				OUStringBuffer sBuf;
1489 				GetExport().GetMM100UnitConverter().convertMeasure(sBuf,
1490 																 nTabPosition);
1491 				GetExport().AddAttribute(XML_NAMESPACE_STYLE,
1492 										 XML_POSITION,
1493 										 sBuf.makeStringAndClear());
1494 			}
1495 
1496 			// fill char ("leader char")
1497 			if (bFillCharOK && (sFillChar.getLength() > 0))
1498 			{
1499 				GetExport().AddAttribute(XML_NAMESPACE_STYLE,
1500 										 XML_LEADER_CHAR, sFillChar);
1501 			}
1502 
1503             // #i21237#
1504             if (bWithTabStopOK && ! bWithTabStop)
1505             {
1506                	GetExport().AddAttribute(XML_NAMESPACE_STYLE,
1507 										 XML_WITH_TAB,
1508 										 XML_FALSE);
1509             }
1510 		}
1511 
1512 		// bibliography data
1513 		if (TOK_TTYPE_BIBLIOGRAPHY == nTokenType)
1514 		{
1515 			OSL_ENSURE(bBibliographyDataOK, "need bibl data");
1516 			OUStringBuffer sBuf;
1517 			if (SvXMLUnitConverter::convertEnum( sBuf, nBibliographyData,
1518 												 aBibliographyDataFieldMap ) )
1519 			{
1520 				GetExport().AddAttribute(XML_NAMESPACE_TEXT,
1521 										 XML_BIBLIOGRAPHY_DATA_FIELD,
1522 										 sBuf.makeStringAndClear());
1523 			}
1524 		}
1525 
1526 		// chapter info
1527 		if (TOK_TTYPE_CHAPTER_INFO == nTokenType)
1528 		{
1529 			OSL_ENSURE(bChapterFormatOK, "need chapter info");
1530 			GetExport().AddAttribute(
1531 				XML_NAMESPACE_TEXT, XML_DISPLAY,
1532 				XMLTextFieldExport::MapChapterDisplayFormat(nChapterFormat));
1533 //---> i53420
1534             if (bLevelOK)
1535                 GetExport().AddAttribute(XML_NAMESPACE_TEXT, XML_OUTLINE_LEVEL,
1536                                      OUString::valueOf((sal_Int32)nLevel));
1537 //<---
1538 		}
1539 
1540 //--->i53420
1541         if (TOK_TTYPE_ENTRY_NUMBER == nTokenType)
1542         {
1543             if (bChapterFormatOK)
1544                 GetExport().AddAttribute(
1545                     XML_NAMESPACE_TEXT, XML_DISPLAY,
1546                     XMLTextFieldExport::MapChapterDisplayFormat(nChapterFormat));
1547 
1548             if (bLevelOK)
1549                 GetExport().AddAttribute(XML_NAMESPACE_TEXT, XML_OUTLINE_LEVEL,
1550                                      OUString::valueOf((sal_Int32)nLevel));
1551         }
1552 //<---
1553 		// export template
1554 		SvXMLElementExport aTemplateElement(GetExport(), XML_NAMESPACE_TEXT,
1555 											GetXMLToken(eElement),
1556                                             sal_True, sal_False)
1557             ;
1558 
1559 		// entry text or span element: write text
1560 		if (TOK_TTYPE_TEXT == nTokenType)
1561 		{
1562 			GetExport().Characters(sText);
1563 		}
1564 	}
1565 }
1566 
ExportLevelParagraphStyles(Reference<XIndexReplace> & xLevelParagraphStyles)1567 void XMLSectionExport::ExportLevelParagraphStyles(
1568 	Reference<XIndexReplace> & xLevelParagraphStyles)
1569 {
1570 	// iterate over levels
1571 	sal_Int32 nPLevelCount = xLevelParagraphStyles->getCount();
1572 	for(sal_Int32 nLevel = 0; nLevel < nPLevelCount; nLevel++)
1573 	{
1574 		Any aAny = xLevelParagraphStyles->getByIndex(nLevel);
1575 		Sequence<OUString> aStyleNames;
1576 		aAny >>= aStyleNames;
1577 
1578 		// export only if at least one style is contained
1579 		sal_Int32 nNamesCount = aStyleNames.getLength();
1580 		if (nNamesCount > 0)
1581 		{
1582 			// level attribute; we count 1..10; API 0..9
1583 			OUStringBuffer sBuf;
1584 			sal_Int32 nLevelPlusOne = nLevel + 1;
1585 			SvXMLUnitConverter::convertNumber(sBuf, nLevelPlusOne);
1586 			GetExport().AddAttribute(XML_NAMESPACE_TEXT,
1587 									 XML_OUTLINE_LEVEL,
1588 									 sBuf.makeStringAndClear());
1589 
1590 			// source styles element
1591 			SvXMLElementExport aParaStyles(GetExport(),
1592 										   XML_NAMESPACE_TEXT,
1593 										   XML_INDEX_SOURCE_STYLES,
1594 										   sal_True, sal_True);
1595 
1596 			// iterate over styles in this level
1597 			for(sal_Int32 nName = 0; nName < nNamesCount; nName++)
1598 			{
1599 				// stylename attribute
1600 				GetExport().AddAttribute(XML_NAMESPACE_TEXT,
1601 										 XML_STYLE_NAME,
1602 							 GetExport().EncodeStyleName( aStyleNames[nName]) );
1603 
1604 				// element
1605 				SvXMLElementExport aParaStyle(GetExport(),
1606 											  XML_NAMESPACE_TEXT,
1607 											  XML_INDEX_SOURCE_STYLE,
1608 											  sal_True, sal_False);
1609 			}
1610 		}
1611 	}
1612 }
1613 
ExportBoolean(const Reference<XPropertySet> & rPropSet,const OUString & sPropertyName,enum XMLTokenEnum eAttributeName,sal_Bool bDefault,sal_Bool bInvert)1614 void XMLSectionExport::ExportBoolean(
1615 	const Reference<XPropertySet> & rPropSet,
1616 	const OUString& sPropertyName,
1617 	enum XMLTokenEnum eAttributeName,
1618 	sal_Bool bDefault,
1619 	sal_Bool bInvert)
1620 {
1621 	OSL_ENSURE(eAttributeName != XML_TOKEN_INVALID, "Need attribute name");
1622 
1623 	Any aAny = rPropSet->getPropertyValue(sPropertyName);
1624 	sal_Bool bTmp = *(sal_Bool*)aAny.getValue();
1625 
1626 	// value = value ^ bInvert
1627 	// omit if value == default
1628 	// negate forces sal_Bool to 0/1, making them comparable
1629 	if ((!(bTmp ^ bInvert)) != (!bDefault))
1630 	{
1631 		// export non-default value (since default is omitted)
1632 		GetExport().AddAttribute(XML_NAMESPACE_TEXT,
1633                                  eAttributeName,
1634                                  bDefault ? XML_FALSE : XML_TRUE);
1635 	}
1636 }
1637 
1638 const sal_Char sAPI_FieldMaster_Bibliography[] =
1639 								"com.sun.star.text.FieldMaster.Bibliography";
1640 const sal_Char sAPI_SortKey[] = "SortKey";
1641 const sal_Char sAPI_IsSortAscending[] = "IsSortAscending";
1642 
ExportBibliographyConfiguration(SvXMLExport & rExport)1643 void XMLSectionExport::ExportBibliographyConfiguration(SvXMLExport& rExport)
1644 {
1645 	// first: get field master (via text field supplier)
1646 	Reference<XTextFieldsSupplier> xTextFieldsSupp( rExport.GetModel(),
1647                                                     UNO_QUERY );
1648     if ( xTextFieldsSupp.is() )
1649     {
1650 		const OUString sFieldMaster_Bibliography(
1651 			RTL_CONSTASCII_USTRINGPARAM(sAPI_FieldMaster_Bibliography));
1652 
1653         // get bibliography field master
1654         Reference<XNameAccess> xMasters =
1655             xTextFieldsSupp->getTextFieldMasters();
1656         if ( xMasters->hasByName(sFieldMaster_Bibliography) )
1657         {
1658             Any aAny =
1659                 xMasters->getByName(sFieldMaster_Bibliography);
1660             Reference<XPropertySet> xPropSet;
1661             aAny >>= xPropSet;
1662 
1663             OSL_ENSURE( xPropSet.is(), "field master must have XPropSet" );
1664 
1665             const OUString sBracketBefore(
1666                 RTL_CONSTASCII_USTRINGPARAM("BracketBefore"));
1667             const OUString sBracketAfter(
1668                 RTL_CONSTASCII_USTRINGPARAM("BracketAfter"));
1669             const OUString sIsNumberEntries(
1670                 RTL_CONSTASCII_USTRINGPARAM("IsNumberEntries"));
1671             const OUString sIsSortByPosition(
1672                 RTL_CONSTASCII_USTRINGPARAM("IsSortByPosition"));
1673             const OUString sSortKeys(
1674                 RTL_CONSTASCII_USTRINGPARAM("SortKeys"));
1675             const OUString sSortAlgorithm(
1676                 RTL_CONSTASCII_USTRINGPARAM("SortAlgorithm"));
1677             const OUString sLocale(
1678                 RTL_CONSTASCII_USTRINGPARAM("Locale"));
1679 
1680 			OUString sTmp;
1681 
1682 			aAny = xPropSet->getPropertyValue(sBracketBefore);
1683 			aAny >>= sTmp;
1684 			rExport.AddAttribute(XML_NAMESPACE_TEXT, XML_PREFIX, sTmp);
1685 
1686 			aAny = xPropSet->getPropertyValue(sBracketAfter);
1687 			aAny >>= sTmp;
1688 			rExport.AddAttribute(XML_NAMESPACE_TEXT, XML_SUFFIX, sTmp);
1689 
1690 			aAny = xPropSet->getPropertyValue(sIsNumberEntries);
1691 			if (*(sal_Bool*)aAny.getValue())
1692 			{
1693 				rExport.AddAttribute(XML_NAMESPACE_TEXT,
1694                                      XML_NUMBERED_ENTRIES, XML_TRUE);
1695 			}
1696 
1697 			aAny = xPropSet->getPropertyValue(sIsSortByPosition);
1698 			if (! *(sal_Bool*)aAny.getValue())
1699 			{
1700 				rExport.AddAttribute(XML_NAMESPACE_TEXT,
1701                                      XML_SORT_BY_POSITION, XML_FALSE);
1702 			}
1703 
1704             // sort algorithm
1705             aAny = xPropSet->getPropertyValue(sSortAlgorithm);
1706             OUString sAlgorithm;
1707             aAny >>= sAlgorithm;
1708             if( sAlgorithm.getLength() > 0 )
1709             {
1710                 rExport.AddAttribute( XML_NAMESPACE_TEXT,
1711                                       XML_SORT_ALGORITHM, sAlgorithm );
1712             }
1713 
1714             // locale
1715             aAny = xPropSet->getPropertyValue(sLocale);
1716             Locale aLocale;
1717             aAny >>= aLocale;
1718             rExport.AddAttribute(XML_NAMESPACE_FO, XML_LANGUAGE,
1719                                      aLocale.Language);
1720             rExport.AddAttribute(XML_NAMESPACE_FO, XML_COUNTRY,
1721                                      aLocale.Country);
1722 
1723 			// configuration element
1724 			SvXMLElementExport aElement(rExport, XML_NAMESPACE_TEXT,
1725 										XML_BIBLIOGRAPHY_CONFIGURATION,
1726 										sal_True, sal_True);
1727 
1728 			// sort keys
1729 			aAny = xPropSet->getPropertyValue(sSortKeys);
1730 			Sequence<Sequence<PropertyValue> > aKeys;
1731 			aAny >>= aKeys;
1732 			sal_Int32 nKeysCount = aKeys.getLength();
1733 			for(sal_Int32 nKeys = 0; nKeys < nKeysCount; nKeys++)
1734 			{
1735 				Sequence<PropertyValue> & rKey = aKeys[nKeys];
1736 
1737 				sal_Int32 nKeyCount = rKey.getLength();
1738 				for(sal_Int32 nPropertyKey = 0; nPropertyKey < nKeyCount; nPropertyKey++)
1739 				{
1740 					PropertyValue& rValue = rKey[nPropertyKey];
1741 
1742 					if (rValue.Name.equalsAsciiL(sAPI_SortKey,
1743 												 sizeof(sAPI_SortKey)-1))
1744 					{
1745 						sal_Int16 nKey = 0;
1746 						rValue.Value >>= nKey;
1747 						OUStringBuffer sBuf;
1748 						if (SvXMLUnitConverter::convertEnum( sBuf, nKey,
1749 												 aBibliographyDataFieldMap ) )
1750 						{
1751 							rExport.AddAttribute(XML_NAMESPACE_TEXT, XML_KEY,
1752 												 sBuf.makeStringAndClear());
1753 						}
1754 					}
1755 					else if (rValue.Name.equalsAsciiL(sAPI_IsSortAscending,
1756 											sizeof(sAPI_IsSortAscending)-1))
1757 					{
1758 						sal_Bool bTmp = *(sal_Bool*)rValue.Value.getValue();
1759 						rExport.AddAttribute(XML_NAMESPACE_TEXT,
1760                                              XML_SORT_ASCENDING,
1761                                              bTmp ? XML_TRUE : XML_FALSE);
1762 					}
1763 				}
1764 
1765 				SvXMLElementExport aKeyElem(rExport,
1766 											XML_NAMESPACE_TEXT, XML_SORT_KEY,
1767 											sal_True, sal_True);
1768 			}
1769 		}
1770 	}
1771 }
1772 
1773 
IsMuteSection(const Reference<XTextSection> & rSection) const1774 sal_Bool XMLSectionExport::IsMuteSection(
1775 	const Reference<XTextSection> & rSection) const
1776 {
1777 	sal_Bool bRet = sal_False;
1778 
1779 	// a section is mute if
1780 	// 1) it exists
1781 	// 2) the SaveLinkedSections flag (at the export) is false
1782 	// 3) the IsGlobalDocumentSection property is true
1783     // 4) it is not an Index
1784 
1785 	if ( (!rExport.IsSaveLinkedSections()) && rSection.is() )
1786 	{
1787 		// walk the section chain and set bRet if any is linked
1788 		for(Reference<XTextSection> aSection(rSection);
1789 			aSection.is();
1790 			aSection = aSection->getParentSection())
1791 		{
1792 			// check if it is a global document section (linked or index)
1793 			Reference<XPropertySet> xPropSet(aSection, UNO_QUERY);
1794 			if (xPropSet.is())
1795 			{
1796 				Any aAny = xPropSet->getPropertyValue(sIsGlobalDocumentSection);
1797 
1798                 if ( *(sal_Bool*)aAny.getValue() )
1799                 {
1800                     Reference<XDocumentIndex> xIndex;
1801                     if (! GetIndex(rSection, xIndex))
1802                     {
1803                         bRet = sal_True;
1804 
1805                         // early out if result is known
1806                         break;
1807                     }
1808                 }
1809 			}
1810 			// section has no properties: ignore
1811 		}
1812 	}
1813 	// else: no section, or always save sections: default (false)
1814 
1815 	return bRet;
1816 }
1817 
IsMuteSection(const Reference<XTextContent> & rSection,sal_Bool bDefault) const1818 sal_Bool XMLSectionExport::IsMuteSection(
1819 	const Reference<XTextContent> & rSection,
1820 	sal_Bool bDefault) const
1821 {
1822 	// default: like default argument
1823 	sal_Bool bRet = bDefault;
1824 
1825 	Reference<XPropertySet> xPropSet(rSection->getAnchor(), UNO_QUERY);
1826 	if (xPropSet.is())
1827 	{
1828 		if (xPropSet->getPropertySetInfo()->hasPropertyByName(sTextSection))
1829 		{
1830 			Any aAny = xPropSet->getPropertyValue(sTextSection);
1831 			Reference<XTextSection> xSection;
1832 			aAny >>= xSection;
1833 
1834 			bRet = IsMuteSection(xSection);
1835 		}
1836 		// else: return default
1837 	}
1838 	// else: return default
1839 
1840 	return bRet;
1841 }
1842 
IsInSection(const Reference<XTextSection> & rEnclosingSection,const Reference<XTextContent> & rContent,sal_Bool bDefault)1843 sal_Bool XMLSectionExport::IsInSection(
1844 	const Reference<XTextSection> & rEnclosingSection,
1845 	const Reference<XTextContent> & rContent,
1846 	sal_Bool bDefault)
1847 {
1848 	// default: like default argument
1849 	sal_Bool bRet = bDefault;
1850 	OSL_ENSURE(rEnclosingSection.is(), "enclosing section expected");
1851 
1852 	Reference<XPropertySet> xPropSet(rContent, UNO_QUERY);
1853 	if (xPropSet.is())
1854 	{
1855 		if (xPropSet->getPropertySetInfo()->hasPropertyByName(sTextSection))
1856 		{
1857 			Any aAny = xPropSet->getPropertyValue(sTextSection);
1858 			Reference<XTextSection> xSection;
1859 			aAny >>= xSection;
1860 
1861 			// now walk chain of text sections (if we have one)
1862 			if (xSection.is())
1863 			{
1864 				do
1865 				{
1866 					bRet = (rEnclosingSection == xSection);
1867 					xSection = xSection->getParentSection();
1868 				}
1869 				while (!bRet && xSection.is());
1870 			}
1871 			else
1872 				bRet = sal_False;	// no section -> can't be inside
1873 		}
1874 		// else: no TextSection property -> return default
1875 	}
1876 	// else: no XPropertySet -> return default
1877 
1878 	return bRet;
1879 }
1880 
1881 
ExportMasterDocHeadingDummies()1882 void XMLSectionExport::ExportMasterDocHeadingDummies()
1883 {
1884 	if( bHeadingDummiesExported )
1885 		return;
1886 
1887 	Reference< XChapterNumberingSupplier > xCNSupplier( rExport.GetModel(),
1888 														UNO_QUERY );
1889 
1890 	Reference< XIndexReplace > xChapterNumbering;
1891 	if( xCNSupplier.is() )
1892 		xChapterNumbering = xCNSupplier->getChapterNumberingRules();
1893 
1894 	if( !xChapterNumbering.is() )
1895 		return;
1896 
1897 	sal_Int32 nCount = xChapterNumbering->getCount();
1898 	for( sal_Int32 nLevel = 0; nLevel < nCount; nLevel++ )
1899 	{
1900 		OUString sStyle;
1901 		Sequence<PropertyValue> aProperties;
1902 		xChapterNumbering->getByIndex( nLevel ) >>= aProperties;
1903 		for( sal_Int32 i = 0; i < aProperties.getLength(); i++ )
1904 		{
1905 			if( aProperties[i].Name == sHeadingStyleName )
1906 			{
1907 				aProperties[i].Value >>= sStyle;
1908 				break;
1909 			}
1910 		}
1911 		if( sStyle.getLength() > 0 )
1912 		{
1913 			GetExport().AddAttribute( XML_NAMESPACE_TEXT, XML_STYLE_NAME,
1914 									  GetExport().EncodeStyleName( sStyle ) );
1915 
1916 			OUStringBuffer sTmp;
1917 			sTmp.append( nLevel + 1 );
1918 			GetExport().AddAttribute( XML_NAMESPACE_TEXT, XML_LEVEL,
1919 								  	  sTmp.makeStringAndClear() );
1920 			SvXMLElementExport aElem( GetExport(), XML_NAMESPACE_TEXT, XML_H,
1921 								  	  sal_True, sal_False );
1922 		}
1923 	}
1924 
1925 	bHeadingDummiesExported  = sal_True;
1926 }
1927