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