LCOV - code coverage report
Current view: top level - xmloff/source/text - XMLRedlineExport.cxx (source / functions) Hit Total Coverage
Test: commit e02a6cb2c3e2b23b203b422e4e0680877f232636 Lines: 0 255 0.0 %
Date: 2014-04-14 Functions: 0 20 0.0 %
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 "XMLRedlineExport.hxx"
      21             : #include <tools/debug.hxx>
      22             : #include <rtl/ustring.hxx>
      23             : #include <rtl/ustrbuf.hxx>
      24             : #include <com/sun/star/beans/XPropertySet.hpp>
      25             : #include <com/sun/star/beans/UnknownPropertyException.hpp>
      26             : #include <com/sun/star/container/XEnumerationAccess.hpp>
      27             : 
      28             : #include <com/sun/star/container/XEnumeration.hpp>
      29             : #include <com/sun/star/document/XRedlinesSupplier.hpp>
      30             : #include <com/sun/star/text/XText.hpp>
      31             : #include <com/sun/star/text/XTextContent.hpp>
      32             : #include <com/sun/star/text/XTextSection.hpp>
      33             : #include <com/sun/star/util/DateTime.hpp>
      34             : 
      35             : #include <sax/tools/converter.hxx>
      36             : 
      37             : #include <xmloff/xmltoken.hxx>
      38             : #include <xmloff/xmlnmspe.hxx>
      39             : #include <xmloff/xmlexp.hxx>
      40             : #include <xmloff/xmluconv.hxx>
      41             : 
      42             : 
      43             : using namespace ::com::sun::star;
      44             : using namespace ::xmloff::token;
      45             : 
      46             : using ::com::sun::star::beans::PropertyValue;
      47             : using ::com::sun::star::beans::XPropertySet;
      48             : using ::com::sun::star::beans::UnknownPropertyException;
      49             : using ::com::sun::star::document::XRedlinesSupplier;
      50             : using ::com::sun::star::container::XEnumerationAccess;
      51             : using ::com::sun::star::container::XEnumeration;
      52             : using ::com::sun::star::text::XText;
      53             : using ::com::sun::star::text::XTextContent;
      54             : using ::com::sun::star::text::XTextSection;
      55             : using ::com::sun::star::uno::Any;
      56             : using ::com::sun::star::uno::Reference;
      57             : using ::com::sun::star::uno::Sequence;
      58             : using ::std::list;
      59             : 
      60             : 
      61           0 : XMLRedlineExport::XMLRedlineExport(SvXMLExport& rExp)
      62             : :   sDelete("Delete")
      63           0 : ,   sDeletion(GetXMLToken(XML_DELETION))
      64             : ,   sFormat("Format")
      65           0 : ,   sFormatChange(GetXMLToken(XML_FORMAT_CHANGE))
      66             : ,   sInsert("Insert")
      67           0 : ,   sInsertion(GetXMLToken(XML_INSERTION))
      68             : ,   sIsCollapsed("IsCollapsed")
      69             : ,   sIsStart("IsStart")
      70             : ,   sRedlineAuthor("RedlineAuthor")
      71             : ,   sRedlineComment("RedlineComment")
      72             : ,   sRedlineDateTime("RedlineDateTime")
      73             : ,   sRedlineSuccessorData("RedlineSuccessorData")
      74             : ,   sRedlineText("RedlineText")
      75             : ,   sRedlineType("RedlineType")
      76             : ,   sStyle("Style")
      77             : ,   sTextTable("TextTable")
      78             : ,   sUnknownChange("UnknownChange")
      79             : ,   sStartRedline("StartRedline")
      80             : ,   sEndRedline("EndRedline")
      81             : ,   sRedlineIdentifier("RedlineIdentifier")
      82             : ,   sIsInHeaderFooter("IsInHeaderFooter")
      83             : ,   sRedlineProtectionKey("RedlineProtectionKey")
      84             : ,   sRecordChanges("RecordChanges")
      85             : ,   sMergeLastPara("MergeLastPara")
      86             : ,   sChangePrefix("ct")
      87             : ,   rExport(rExp)
      88           0 : ,   pCurrentChangesList(NULL)
      89             : {
      90           0 : }
      91             : 
      92             : 
      93           0 : XMLRedlineExport::~XMLRedlineExport()
      94             : {
      95             :     // delete changes lists
      96           0 :     for( ChangesMapType::iterator aIter = aChangeMap.begin();
      97           0 :          aIter != aChangeMap.end();
      98             :          ++aIter )
      99             :     {
     100           0 :         delete aIter->second;
     101             :     }
     102           0 :     aChangeMap.clear();
     103           0 : }
     104             : 
     105             : 
     106           0 : void XMLRedlineExport::ExportChange(
     107             :     const Reference<XPropertySet> & rPropSet,
     108             :     sal_Bool bAutoStyle)
     109             : {
     110           0 :     if (bAutoStyle)
     111             :     {
     112             :         // For the headers/footers, we have to collect the autostyles
     113             :         // here.  For the general case, however, it's better to collet
     114             :         // the autostyles by iterating over the global redline
     115             :         // list. So that's what we do: Here, we collect autostyles
     116             :         // only if we have no current list of changes. For the
     117             :         // main-document case, the autostyles are collected in
     118             :         // ExportChangesListAutoStyles().
     119           0 :         if (pCurrentChangesList != NULL)
     120           0 :             ExportChangeAutoStyle(rPropSet);
     121             :     }
     122             :     else
     123             :     {
     124           0 :         ExportChangeInline(rPropSet);
     125             :     }
     126           0 : }
     127             : 
     128             : 
     129           0 : void XMLRedlineExport::ExportChangesList(sal_Bool bAutoStyles)
     130             : {
     131           0 :     if (bAutoStyles)
     132             :     {
     133           0 :         ExportChangesListAutoStyles();
     134             :     }
     135             :     else
     136             :     {
     137           0 :         ExportChangesListElements();
     138             :     }
     139           0 : }
     140             : 
     141             : 
     142           0 : void XMLRedlineExport::ExportChangesList(
     143             :     const Reference<XText> & rText,
     144             :     sal_Bool bAutoStyles)
     145             : {
     146             :     // in the header/footer case, auto styles are collected from the
     147             :     // inline change elements.
     148           0 :     if (bAutoStyles)
     149           0 :         return;
     150             : 
     151             :     // look for changes list for this XText
     152           0 :     ChangesMapType::iterator aFind = aChangeMap.find(rText);
     153           0 :     if (aFind != aChangeMap.end())
     154             :     {
     155           0 :         ChangesListType* pChangesList = aFind->second;
     156             : 
     157             :         // export only if changes are found
     158           0 :         if (pChangesList->size() > 0)
     159             :         {
     160             :             // changes container element
     161             :             SvXMLElementExport aChanges(rExport, XML_NAMESPACE_TEXT,
     162             :                                         XML_TRACKED_CHANGES,
     163           0 :                                         true, true);
     164             : 
     165             :             // iterate over changes list
     166           0 :             for( ChangesListType::iterator aIter = pChangesList->begin();
     167           0 :                  aIter != pChangesList->end();
     168             :                  ++aIter )
     169             :             {
     170           0 :                 ExportChangedRegion( *aIter );
     171           0 :             }
     172             :         }
     173             :         // else: changes list empty -> ignore
     174             :     }
     175             :     // else: no changes list found -> empty
     176             : }
     177             : 
     178           0 : void XMLRedlineExport::SetCurrentXText(
     179             :     const Reference<XText> & rText)
     180             : {
     181           0 :     if (rText.is())
     182             :     {
     183             :         // look for appropriate list in map; use the found one, or create new
     184           0 :         ChangesMapType::iterator aIter = aChangeMap.find(rText);
     185           0 :         if (aIter == aChangeMap.end())
     186             :         {
     187           0 :             ChangesListType* pList = new ChangesListType;
     188           0 :             aChangeMap[rText] = pList;
     189           0 :             pCurrentChangesList = pList;
     190             :         }
     191             :         else
     192           0 :             pCurrentChangesList = aIter->second;
     193             :     }
     194             :     else
     195             :     {
     196             :         // don't record changes
     197           0 :         SetCurrentXText();
     198             :     }
     199           0 : }
     200             : 
     201           0 : void XMLRedlineExport::SetCurrentXText()
     202             : {
     203           0 :     pCurrentChangesList = NULL;
     204           0 : }
     205             : 
     206             : 
     207           0 : void XMLRedlineExport::ExportChangesListElements()
     208             : {
     209             :     // get redlines (aka tracked changes) from the model
     210           0 :     Reference<XRedlinesSupplier> xSupplier(rExport.GetModel(), uno::UNO_QUERY);
     211           0 :     if (xSupplier.is())
     212             :     {
     213           0 :         Reference<XEnumerationAccess> aEnumAccess = xSupplier->getRedlines();
     214             : 
     215             :         // redline protection key
     216           0 :         Reference<XPropertySet> aDocPropertySet( rExport.GetModel(),
     217           0 :                                                  uno::UNO_QUERY );
     218             :         // redlining enabled?
     219           0 :         sal_Bool bEnabled = *(sal_Bool*)aDocPropertySet->getPropertyValue(
     220           0 :                                                 sRecordChanges ).getValue();
     221             : 
     222             :         // only export if we have redlines or attributes
     223           0 :         if ( aEnumAccess->hasElements() || bEnabled )
     224             :         {
     225             : 
     226             :             // export only if we have changes, but tracking is not enabled
     227           0 :             if ( !bEnabled != !aEnumAccess->hasElements() )
     228             :             {
     229             :                 rExport.AddAttribute(
     230             :                     XML_NAMESPACE_TEXT, XML_TRACK_CHANGES,
     231           0 :                     bEnabled ? XML_TRUE : XML_FALSE );
     232             :             }
     233             : 
     234             :             // changes container element
     235             :             SvXMLElementExport aChanges(rExport, XML_NAMESPACE_TEXT,
     236             :                                         XML_TRACKED_CHANGES,
     237           0 :                                         true, true);
     238             : 
     239             :             // get enumeration and iterate over elements
     240           0 :             Reference<XEnumeration> aEnum = aEnumAccess->createEnumeration();
     241           0 :             while (aEnum->hasMoreElements())
     242             :             {
     243           0 :                 Any aAny = aEnum->nextElement();
     244           0 :                 Reference<XPropertySet> xPropSet;
     245           0 :                 aAny >>= xPropSet;
     246             : 
     247             :                 DBG_ASSERT(xPropSet.is(),
     248             :                            "can't get XPropertySet; skipping Redline");
     249           0 :                 if (xPropSet.is())
     250             :                 {
     251             :                     // export only if not in header or footer
     252             :                     // (those must be exported with their XText)
     253           0 :                     aAny = xPropSet->getPropertyValue(sIsInHeaderFooter);
     254           0 :                     if (! *(sal_Bool*)aAny.getValue())
     255             :                     {
     256             :                         // and finally, export change
     257           0 :                         ExportChangedRegion(xPropSet);
     258             :                     }
     259             :                 }
     260             :                 // else: no XPropertySet -> no export
     261           0 :             }
     262           0 :         }
     263             :         // else: no redlines -> no export
     264           0 :     }
     265             :     // else: no XRedlineSupplier -> no export
     266           0 : }
     267             : 
     268           0 : void XMLRedlineExport::ExportChangeAutoStyle(
     269             :     const Reference<XPropertySet> & rPropSet)
     270             : {
     271             :     // record change (if changes should be recorded)
     272           0 :     if (NULL != pCurrentChangesList)
     273             :     {
     274             :         // put redline in list if it's collapsed or the redline start
     275           0 :         Any aIsStart = rPropSet->getPropertyValue(sIsStart);
     276           0 :         Any aIsCollapsed = rPropSet->getPropertyValue(sIsCollapsed);
     277             : 
     278           0 :         if ( *(sal_Bool*)aIsStart.getValue() ||
     279           0 :              *(sal_Bool*)aIsCollapsed.getValue() )
     280           0 :             pCurrentChangesList->push_back(rPropSet);
     281             :     }
     282             : 
     283             :     // get XText for export of redline auto styles
     284           0 :     Any aAny = rPropSet->getPropertyValue(sRedlineText);
     285           0 :     Reference<XText> xText;
     286           0 :     aAny >>= xText;
     287           0 :     if (xText.is())
     288             :     {
     289             :         // export the auto styles
     290           0 :         rExport.GetTextParagraphExport()->collectTextAutoStyles(xText);
     291           0 :     }
     292           0 : }
     293             : 
     294           0 : void XMLRedlineExport::ExportChangesListAutoStyles()
     295             : {
     296             :     // get redlines (aka tracked changes) from the model
     297           0 :     Reference<XRedlinesSupplier> xSupplier(rExport.GetModel(), uno::UNO_QUERY);
     298           0 :     if (xSupplier.is())
     299             :     {
     300           0 :         Reference<XEnumerationAccess> aEnumAccess = xSupplier->getRedlines();
     301             : 
     302             :         // only export if we actually have redlines
     303           0 :         if (aEnumAccess->hasElements())
     304             :         {
     305             :             // get enumeration and iterate over elements
     306           0 :             Reference<XEnumeration> aEnum = aEnumAccess->createEnumeration();
     307           0 :             while (aEnum->hasMoreElements())
     308             :             {
     309           0 :                 Any aAny = aEnum->nextElement();
     310           0 :                 Reference<XPropertySet> xPropSet;
     311           0 :                 aAny >>= xPropSet;
     312             : 
     313             :                 DBG_ASSERT(xPropSet.is(),
     314             :                            "can't get XPropertySet; skipping Redline");
     315           0 :                 if (xPropSet.is())
     316             :                 {
     317             : 
     318             :                     // export only if not in header or footer
     319             :                     // (those must be exported with their XText)
     320           0 :                     aAny = xPropSet->getPropertyValue(sIsInHeaderFooter);
     321           0 :                     if (! *(sal_Bool*)aAny.getValue())
     322             :                     {
     323           0 :                         ExportChangeAutoStyle(xPropSet);
     324             :                     }
     325             :                 }
     326           0 :             }
     327           0 :         }
     328           0 :     }
     329           0 : }
     330             : 
     331           0 : void XMLRedlineExport::ExportChangeInline(
     332             :     const Reference<XPropertySet> & rPropSet)
     333             : {
     334             :     // determine element name (depending on collapsed, start/end)
     335           0 :     enum XMLTokenEnum eElement = XML_TOKEN_INVALID;
     336           0 :     Any aAny = rPropSet->getPropertyValue(sIsCollapsed);
     337           0 :     sal_Bool bCollapsed = *(sal_Bool *)aAny.getValue();
     338           0 :     sal_Bool bStart = sal_True; // ignored if bCollapsed = sal_True
     339           0 :     if (bCollapsed)
     340             :     {
     341           0 :         eElement = XML_CHANGE;
     342             :     }
     343             :     else
     344             :     {
     345           0 :         aAny = rPropSet->getPropertyValue(sIsStart);
     346           0 :         bStart = *(sal_Bool *)aAny.getValue();
     347           0 :         eElement = bStart ? XML_CHANGE_START : XML_CHANGE_END;
     348             :     }
     349             : 
     350           0 :     if (XML_TOKEN_INVALID != eElement)
     351             :     {
     352             :         // we always need the ID
     353             :         rExport.AddAttribute(XML_NAMESPACE_TEXT, XML_CHANGE_ID,
     354           0 :                              GetRedlineID(rPropSet));
     355             : 
     356             :         // export the element (no whitespace because we're in the text body)
     357             :         SvXMLElementExport aChangeElem(rExport, XML_NAMESPACE_TEXT,
     358           0 :                                        eElement, false, false);
     359           0 :     }
     360           0 : }
     361             : 
     362             : 
     363           0 : void XMLRedlineExport::ExportChangedRegion(
     364             :     const Reference<XPropertySet> & rPropSet)
     365             : {
     366             :     // Redline-ID
     367           0 :     rExport.AddAttributeIdLegacy(XML_NAMESPACE_TEXT, GetRedlineID(rPropSet));
     368             : 
     369             :     // merge-last-paragraph
     370           0 :     Any aAny = rPropSet->getPropertyValue(sMergeLastPara);
     371           0 :     if( ! *(sal_Bool*)aAny.getValue() )
     372             :         rExport.AddAttribute(XML_NAMESPACE_TEXT, XML_MERGE_LAST_PARAGRAPH,
     373           0 :                              XML_FALSE);
     374             : 
     375             :     // export change region element
     376             :     SvXMLElementExport aChangedRegion(rExport, XML_NAMESPACE_TEXT,
     377           0 :                                       XML_CHANGED_REGION, true, true);
     378             : 
     379             : 
     380             :     // scope for (first) change element
     381             :     {
     382           0 :         aAny = rPropSet->getPropertyValue(sRedlineType);
     383           0 :         OUString sType;
     384           0 :         aAny >>= sType;
     385             :         SvXMLElementExport aChange(rExport, XML_NAMESPACE_TEXT,
     386           0 :                                    ConvertTypeName(sType), true, true);
     387             : 
     388           0 :         ExportChangeInfo(rPropSet);
     389             : 
     390             :         // get XText from the redline and export (if the XText exists)
     391           0 :         aAny = rPropSet->getPropertyValue(sRedlineText);
     392           0 :         Reference<XText> xText;
     393           0 :         aAny >>= xText;
     394           0 :         if (xText.is())
     395             :         {
     396           0 :             rExport.GetTextParagraphExport()->exportText(xText);
     397             :             // default parameters: bProgress, bExportParagraph ???
     398           0 :         }
     399             :         // else: no text interface -> content is inline and will
     400             :         //       be exported there
     401             :     }
     402             : 
     403             :     // changed change? Hierarchical changes can onl be two levels
     404             :     // deep. Here we check for the second level.
     405           0 :     aAny = rPropSet->getPropertyValue(sRedlineSuccessorData);
     406           0 :     Sequence<PropertyValue> aSuccessorData;
     407           0 :     aAny >>= aSuccessorData;
     408             : 
     409             :     // if we actually got a hierarchical change, make element and
     410             :     // process change info
     411           0 :     if (aSuccessorData.getLength() > 0)
     412             :     {
     413             :         // The only change that can be "undone" is an insertion -
     414             :         // after all, you can't re-insert an deletion, but you can
     415             :         // delete an insertion. This assumption is asserted in
     416             :         // ExportChangeInfo(Sequence<PropertyValue>&).
     417             :         SvXMLElementExport aSecondChangeElem(
     418             :             rExport, XML_NAMESPACE_TEXT, XML_INSERTION,
     419           0 :             true, true);
     420             : 
     421           0 :         ExportChangeInfo(aSuccessorData);
     422           0 :     }
     423             :     // else: no hierarchical change
     424           0 : }
     425             : 
     426             : 
     427           0 : const OUString XMLRedlineExport::ConvertTypeName(
     428             :     const OUString& sApiName)
     429             : {
     430           0 :     if (sApiName == sDelete)
     431             :     {
     432           0 :         return sDeletion;
     433             :     }
     434           0 :     else if (sApiName == sInsert)
     435             :     {
     436           0 :         return sInsertion;
     437             :     }
     438           0 :     else if (sApiName == sFormat)
     439             :     {
     440           0 :         return sFormatChange;
     441             :     }
     442             :     else
     443             :     {
     444             :         OSL_FAIL("unknown redline type");
     445           0 :         return sUnknownChange;
     446             :     }
     447             : }
     448             : 
     449             : 
     450             : /** Create a Redline-ID */
     451           0 : const OUString XMLRedlineExport::GetRedlineID(
     452             :     const Reference<XPropertySet> & rPropSet)
     453             : {
     454           0 :     Any aAny = rPropSet->getPropertyValue(sRedlineIdentifier);
     455           0 :     OUString sTmp;
     456           0 :     aAny >>= sTmp;
     457             : 
     458           0 :     OUStringBuffer sBuf(sChangePrefix);
     459           0 :     sBuf.append(sTmp);
     460           0 :     return sBuf.makeStringAndClear();
     461             : }
     462             : 
     463             : 
     464           0 : void XMLRedlineExport::ExportChangeInfo(
     465             :     const Reference<XPropertySet> & rPropSet)
     466             : {
     467             : 
     468             :     SvXMLElementExport aChangeInfo(rExport, XML_NAMESPACE_OFFICE,
     469           0 :                                    XML_CHANGE_INFO, true, true);
     470             : 
     471           0 :     Any aAny = rPropSet->getPropertyValue(sRedlineAuthor);
     472           0 :     OUString sTmp;
     473           0 :     aAny >>= sTmp;
     474           0 :     if (!sTmp.isEmpty())
     475             :     {
     476             :         SvXMLElementExport aCreatorElem( rExport, XML_NAMESPACE_DC,
     477             :                                           XML_CREATOR, true,
     478           0 :                                           false );
     479           0 :         rExport.Characters(sTmp);
     480             :     }
     481             : 
     482           0 :     aAny = rPropSet->getPropertyValue(sRedlineDateTime);
     483           0 :     util::DateTime aDateTime;
     484           0 :     aAny >>= aDateTime;
     485             :     {
     486           0 :         OUStringBuffer sBuf;
     487           0 :         ::sax::Converter::convertDateTime(sBuf, aDateTime, 0);
     488             :         SvXMLElementExport aDateElem( rExport, XML_NAMESPACE_DC,
     489             :                                           XML_DATE, true,
     490           0 :                                           false );
     491           0 :         rExport.Characters(sBuf.makeStringAndClear());
     492             :     }
     493             : 
     494             :     // comment as <text:p> sequence
     495           0 :     aAny = rPropSet->getPropertyValue(sRedlineComment);
     496           0 :     aAny >>= sTmp;
     497           0 :     WriteComment( sTmp );
     498           0 : }
     499             : 
     500           0 : void XMLRedlineExport::ExportChangeInfo(
     501             :     const Sequence<PropertyValue> & rPropertyValues)
     502             : {
     503           0 :     OUString sComment;
     504             : 
     505           0 :     sal_Int32 nCount = rPropertyValues.getLength();
     506           0 :     for(sal_Int32 i = 0; i < nCount; i++)
     507             :     {
     508           0 :         const PropertyValue& rVal = rPropertyValues[i];
     509             : 
     510           0 :         if( rVal.Name.equals(sRedlineAuthor) )
     511             :         {
     512           0 :             OUString sTmp;
     513           0 :             rVal.Value >>= sTmp;
     514           0 :             if (!sTmp.isEmpty())
     515             :             {
     516           0 :                 rExport.AddAttribute(XML_NAMESPACE_OFFICE, XML_CHG_AUTHOR, sTmp);
     517           0 :             }
     518             :         }
     519           0 :         else if( rVal.Name.equals(sRedlineComment) )
     520             :         {
     521           0 :             rVal.Value >>= sComment;
     522             :         }
     523           0 :         else if( rVal.Name.equals(sRedlineDateTime) )
     524             :         {
     525           0 :             util::DateTime aDateTime;
     526           0 :             rVal.Value >>= aDateTime;
     527           0 :             OUStringBuffer sBuf;
     528           0 :             ::sax::Converter::convertDateTime(sBuf, aDateTime, 0);
     529             :             rExport.AddAttribute(XML_NAMESPACE_OFFICE, XML_CHG_DATE_TIME,
     530           0 :                                  sBuf.makeStringAndClear());
     531             :         }
     532           0 :         else if( rVal.Name.equals(sRedlineType) )
     533             :         {
     534             :             // check if this is an insertion; cf. comment at calling location
     535           0 :             OUString sTmp;
     536           0 :             rVal.Value >>= sTmp;
     537             :             DBG_ASSERT(sTmp.equals(sInsert),
     538           0 :                        "hierarchical change must be insertion");
     539             :         }
     540             :         // else: unknown value -> ignore
     541             :     }
     542             : 
     543             :     // finally write element
     544             :     SvXMLElementExport aChangeInfo(rExport, XML_NAMESPACE_OFFICE,
     545           0 :                                    XML_CHANGE_INFO, true, true);
     546             : 
     547           0 :     WriteComment( sComment );
     548           0 : }
     549             : 
     550           0 : void XMLRedlineExport::ExportStartOrEndRedline(
     551             :     const Reference<XPropertySet> & rPropSet,
     552             :     sal_Bool bStart)
     553             : {
     554           0 :     if( ! rPropSet.is() )
     555           0 :         return;
     556             : 
     557             :     // get appropriate (start or end) property
     558           0 :     Any aAny;
     559             :     try
     560             :     {
     561           0 :         aAny = rPropSet->getPropertyValue(bStart ? sStartRedline : sEndRedline);
     562             :     }
     563           0 :     catch(const UnknownPropertyException&)
     564             :     {
     565             :         // If we don't have the property, there's nothing to do.
     566           0 :         return;
     567             :     }
     568             : 
     569           0 :     Sequence<PropertyValue> aValues;
     570           0 :     aAny >>= aValues;
     571           0 :     const PropertyValue* pValues = aValues.getConstArray();
     572             : 
     573             :     // seek for redline properties
     574           0 :     sal_Bool bIsCollapsed = sal_False;
     575           0 :     sal_Bool bIsStart = sal_True;
     576           0 :     OUString sId;
     577           0 :     sal_Bool bIdOK = sal_False; // have we seen an ID?
     578           0 :     sal_Int32 nLength = aValues.getLength();
     579           0 :     for(sal_Int32 i = 0; i < nLength; i++)
     580             :     {
     581           0 :         if (sRedlineIdentifier.equals(pValues[i].Name))
     582             :         {
     583           0 :             pValues[i].Value >>= sId;
     584           0 :             bIdOK = sal_True;
     585             :         }
     586           0 :         else if (sIsCollapsed.equals(pValues[i].Name))
     587             :         {
     588           0 :             bIsCollapsed = *(sal_Bool*)pValues[i].Value.getValue();
     589             :         }
     590           0 :         else if (sIsStart.equals(pValues[i].Name))
     591             :         {
     592           0 :             bIsStart = *(sal_Bool*)pValues[i].Value.getValue();
     593             :         }
     594             :     }
     595             : 
     596           0 :     if( bIdOK )
     597             :     {
     598             :         DBG_ASSERT( !sId.isEmpty(), "Redlines must have IDs" );
     599             : 
     600             :         // TODO: use GetRedlineID or elimiate that function
     601           0 :         OUStringBuffer sBuffer(sChangePrefix);
     602           0 :         sBuffer.append(sId);
     603             : 
     604             :         rExport.AddAttribute(XML_NAMESPACE_TEXT, XML_CHANGE_ID,
     605           0 :                              sBuffer.makeStringAndClear());
     606             : 
     607             :         // export the element
     608             :         // (whitespace because we're not inside paragraphs)
     609             :         SvXMLElementExport aChangeElem(
     610             :             rExport, XML_NAMESPACE_TEXT,
     611             :             bIsCollapsed ? XML_CHANGE :
     612             :                 ( bIsStart ? XML_CHANGE_START : XML_CHANGE_END ),
     613           0 :             true, true);
     614           0 :     }
     615             : }
     616             : 
     617           0 : void XMLRedlineExport::ExportStartOrEndRedline(
     618             :     const Reference<XTextContent> & rContent,
     619             :     sal_Bool bStart)
     620             : {
     621           0 :     Reference<XPropertySet> xPropSet(rContent, uno::UNO_QUERY);
     622           0 :     if (xPropSet.is())
     623             :     {
     624           0 :         ExportStartOrEndRedline(xPropSet, bStart);
     625             :     }
     626             :     else
     627             :     {
     628             :         OSL_FAIL("XPropertySet expected");
     629           0 :     }
     630           0 : }
     631             : 
     632           0 : void XMLRedlineExport::ExportStartOrEndRedline(
     633             :     const Reference<XTextSection> & rSection,
     634             :     sal_Bool bStart)
     635             : {
     636           0 :     Reference<XPropertySet> xPropSet(rSection, uno::UNO_QUERY);
     637           0 :     if (xPropSet.is())
     638             :     {
     639           0 :         ExportStartOrEndRedline(xPropSet, bStart);
     640             :     }
     641             :     else
     642             :     {
     643             :         OSL_FAIL("XPropertySet expected");
     644           0 :     }
     645           0 : }
     646             : 
     647           0 : void XMLRedlineExport::WriteComment(const OUString& rComment)
     648             : {
     649           0 :     if (!rComment.isEmpty())
     650             :     {
     651             :         // iterate over all string-pieces separated by return (0x0a) and
     652             :         // put each inside a paragraph element.
     653           0 :         SvXMLTokenEnumerator aEnumerator(rComment, sal_Char(0x0a));
     654           0 :         OUString aSubString;
     655           0 :         while (aEnumerator.getNextToken(aSubString))
     656             :         {
     657             :             SvXMLElementExport aParagraph(
     658           0 :                 rExport, XML_NAMESPACE_TEXT, XML_P, true, false);
     659           0 :             rExport.Characters(aSubString);
     660           0 :         }
     661             :     }
     662           0 : }
     663             : 
     664             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10