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

Generated by: LCOV version 1.10