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