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