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

Generated by: LCOV version 1.10