LCOV - code coverage report
Current view: top level - xmloff/source/text - XMLSectionExport.cxx (source / functions) Hit Total Coverage
Test: commit c8344322a7af75b84dd3ca8f78b05543a976dfd5 Lines: 530 694 76.4 %
Date: 2015-06-13 12:38:46 Functions: 25 28 89.3 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.11