[Libreoffice-commits] core.git: Branch 'private/Rosemary/change-tracking' - include/xmloff sw/source xmloff/source

Rosemary Sebastian rosemaryseb8 at gmail.com
Wed Jun 22 09:12:33 UTC 2016


 include/xmloff/txtparae.hxx                 |   45 ++
 sw/source/core/unocore/unomapproperties.hxx |    4 
 sw/source/filter/xml/xmlexp.cxx             |    4 
 xmloff/source/text/XMLRedlineExport.cxx     |  132 ++++++
 xmloff/source/text/XMLRedlineExport.hxx     |   17 
 xmloff/source/text/txtparae.cxx             |  552 +++++++++++++++++++++++++++-
 6 files changed, 741 insertions(+), 13 deletions(-)

New commits:
commit 79651457952e910786474c9751178077ca121c06
Author: Rosemary Sebastian <rosemaryseb8 at gmail.com>
Date:   Wed Jun 22 14:37:36 2016 +0530

    Implement export of insertion and deletion changes
    
    Change-Id: I6a8b580dc43c744bb181961ff26c95acd10207cb

diff --git a/include/xmloff/txtparae.hxx b/include/xmloff/txtparae.hxx
index 5e445bd..ce851f8 100644
--- a/include/xmloff/txtparae.hxx
+++ b/include/xmloff/txtparae.hxx
@@ -92,6 +92,7 @@ class XMLOFF_DLLPUBLIC XMLTextParagraphExport : public XMLStyleExport
 
     /// may be NULL (if no redlines should be exported; e.g. in block mode)
     XMLRedlineExport            *pRedlineExport;
+    sal_uInt32                  nParaIdx;
 
     bool                        bProgress;
 
@@ -246,6 +247,11 @@ public:
         const css::uno::Reference< css::beans::XPropertyState > & rPropState,
         const css::uno::Reference< css::beans::XPropertySetInfo > & rPropSetInfo );
 
+    void exportUndoTextRangeEnumeration(
+        const css::uno::Reference< css::container::XEnumeration > & rRangeEnum,
+        const sal_uInt32& rParaIdx,
+        bool bAutoStyles, bool bProgress,
+        bool bPrvChrIsSpc = true );
     void exportTextRangeEnumeration(
         const css::uno::Reference< css::container::XEnumeration > & rRangeEnum,
         bool bAutoStyles, bool bProgress,
@@ -268,6 +274,11 @@ protected:
 
     void exportNumStyles( bool bUsed );
 
+    void exportUndoText(
+        const css::uno::Reference <
+            css::text::XText > & rText,
+        bool bAutoStyles, bool bProgress, bool bExportParagraph, TextPNS eExtensionNS = TextPNS::ODF );
+
     void exportText(
         const css::uno::Reference <
             css::text::XText > & rText,
@@ -278,6 +289,15 @@ protected:
         const css::uno::Reference< css::text::XTextSection > & rBaseSection,
         bool bAutoStyles, bool bProgress, bool bExportParagraph, TextPNS eExtensionNS = TextPNS::ODF );
 
+    bool exportUndoTextContentEnumeration(
+        const css::uno::Reference< css::container::XEnumeration > & rContentEnum,
+        bool bAutoStyles,
+        const css::uno::Reference< css::text::XTextSection > & rBaseSection,
+        bool bProgress,
+        bool bExportParagraph = true,
+        const css::uno::Reference< css::beans::XPropertySet > *pRangePropSet = nullptr,
+        bool bExportLevels = true,
+        TextPNS eExtensionNS = TextPNS::ODF);
     bool exportTextContentEnumeration(
         const css::uno::Reference< css::container::XEnumeration > & rContentEnum,
         bool bAutoStyles,
@@ -287,6 +307,13 @@ protected:
         const css::uno::Reference< css::beans::XPropertySet > *pRangePropSet = nullptr,
         bool bExportLevels = true,
         TextPNS eExtensionNS = TextPNS::ODF);
+    void exportUndoParagraph(
+        const css::uno::Reference< css::text::XTextContent > & rTextContent,
+        const sal_uInt32& rParaIdx,
+        bool bAutoStyles, bool bProgress,
+        bool bExportParagraph,
+        MultiPropertySetHelper& rPropSetHelper,
+        TextPNS eExtensionNS = TextPNS::ODF);
     void exportParagraph(
         const css::uno::Reference< css::text::XTextContent > & rTextContent,
         bool bAutoStyles, bool bProgress,
@@ -531,7 +558,25 @@ public:
     void exportTitleAndDescription( const css::uno::Reference< css::beans::XPropertySet > & rPropSet,
                                     const css::uno::Reference< css::beans::XPropertySetInfo > & rPropSetInfo );
 
+    void setParaIdx(sal_uInt32 rParaIdx)
+    {
+        nParaIdx = rParaIdx;
+    }
+
+    sal_uInt32 getParaIdx()
+    {
+        return nParaIdx;
+    }
+
     // This method exports the given XText
+    void exportUndoText(
+        const css::uno::Reference< css::text::XText > & rText,
+        bool bIsProgress = false,
+        bool bExportParagraph = true, TextPNS eExtensionNS = TextPNS::ODF)
+    {
+        exportUndoText( rText, false, bIsProgress, bExportParagraph, eExtensionNS );
+    }
+
     void exportText(
         const css::uno::Reference< css::text::XText > & rText,
         bool bIsProgress = false,
diff --git a/sw/source/core/unocore/unomapproperties.hxx b/sw/source/core/unocore/unomapproperties.hxx
index e10b7d8..8edcb3b 100644
--- a/sw/source/core/unocore/unomapproperties.hxx
+++ b/sw/source/core/unocore/unomapproperties.hxx
@@ -74,8 +74,8 @@
     {OUString(UNO_NAME_IS_IN_HEADER_FOOTER), 0, cppu::UnoType<bool>::get(),                             PropertyAttribute::MAYBEVOID|PropertyAttribute::READONLY, 0},\
     {OUString(UNO_NAME_REDLINE_TEXT), 0, cppu::UnoType<css::text::XText>::get(),                    PropertyAttribute::MAYBEVOID|PropertyAttribute::READONLY,   0},\
     {OUString(UNO_NAME_MERGE_LAST_PARA), 0, cppu::UnoType<bool>::get(),                             PropertyAttribute::MAYBEVOID|PropertyAttribute::READONLY, 0},\
-    {OUString(UNO_NAME_REDLINE_UNDO_START), 0, cppu::UnoType<bool>::get(),                             PropertyAttribute::MAYBEVOID|PropertyAttribute::READONLY, 0},\
-    {OUString(UNO_NAME_REDLINE_UNDO_END), 0, cppu::UnoType<bool>::get(),                               PropertyAttribute::MAYBEVOID|PropertyAttribute::READONLY, 0},
+    {OUString(UNO_NAME_REDLINE_UNDO_START), 0, cppu::UnoType<sal_uInt32>::get(),                             PropertyAttribute::MAYBEVOID|PropertyAttribute::READONLY, 0},\
+    {OUString(UNO_NAME_REDLINE_UNDO_END), 0, cppu::UnoType<sal_uInt32>::get(),                               PropertyAttribute::MAYBEVOID|PropertyAttribute::READONLY, 0},
 #define COMMON_CRSR_PARA_PROPERTIES_FN_ONLY \
         { OUString(UNO_NAME_PARA_STYLE_NAME), FN_UNO_PARA_STYLE,        cppu::UnoType<OUString>::get(),                PropertyAttribute::MAYBEVOID,     0},                                                       \
         { OUString(UNO_NAME_PAGE_STYLE_NAME), FN_UNO_PAGE_STYLE,        cppu::UnoType<OUString>::get(),         PropertyAttribute::MAYBEVOID|PropertyAttribute::READONLY,   0},                       \
diff --git a/sw/source/filter/xml/xmlexp.cxx b/sw/source/filter/xml/xmlexp.cxx
index 75e2cd0..2812ec5 100644
--- a/sw/source/filter/xml/xmlexp.cxx
+++ b/sw/source/filter/xml/xmlexp.cxx
@@ -495,7 +495,9 @@ void SwXMLExport::ExportUndo_()
 {
     SvXMLElementExport aElem( *this, XML_NAMESPACE_OFFICE, XML_UNDO,
                                 true, true );
-    GetTextParagraphExport()->exportTrackedChanges( false );
+    Reference < XTextDocument > xTextDoc( GetModel(), UNO_QUERY );
+    Reference < XText > xText = xTextDoc->getText();
+    GetTextParagraphExport()->exportUndoText( xText, bShowProgress );
 }
 
 namespace
diff --git a/xmloff/source/text/XMLRedlineExport.cxx b/xmloff/source/text/XMLRedlineExport.cxx
index 4226e4a..aaf776b 100644
--- a/xmloff/source/text/XMLRedlineExport.cxx
+++ b/xmloff/source/text/XMLRedlineExport.cxx
@@ -102,6 +102,17 @@ XMLRedlineExport::~XMLRedlineExport()
     aChangeMap.clear();
 }
 
+void XMLRedlineExport::ExportUndoChange(
+    const Reference<XPropertySet> & rPropSet,
+    const sal_uInt32& rParaIdx,
+    bool bAutoStyle)
+{
+    if (!bAutoStyle)
+    {
+        ExportUndoChangeInfo(rPropSet, rParaIdx);
+    }
+
+}
 
 void XMLRedlineExport::ExportChange(
     const Reference<XPropertySet> & rPropSet,
@@ -119,6 +130,11 @@ void XMLRedlineExport::ExportChange(
         if (pCurrentChangesList != nullptr)
             ExportChangeAutoStyle(rPropSet);
     }
+    else
+    {
+        ExportChangeInline(rPropSet);
+    }
+
 }
 
 
@@ -199,7 +215,6 @@ void XMLRedlineExport::SetCurrentXText()
     pCurrentChangesList = nullptr;
 }
 
-
 void XMLRedlineExport::ExportChangesListElements()
 {
     // get redlines (aka tracked changes) from the model
@@ -324,15 +339,106 @@ void XMLRedlineExport::ExportChangesListAutoStyles()
     }
 }
 
+void XMLRedlineExport::ExportUndoChangeInline(
+    const Reference<XPropertySet> & rPropSet, const sal_uInt32& rParaIdx)
+{
+    // determine element name (depending on collapsed, start/end)
+    {
+        {
+            Any aAny;
+            aAny = rPropSet->getPropertyValue(sRedlineType);
+            OUString sType;
+            aAny >>= sType;
+
+            sal_uInt32 nParagraphIdx = rParaIdx, nCharStart, nCharEnd;
+            rPropSet->getPropertyValue(sRedlineUndoStart) >>= nCharStart;
+            rPropSet->getPropertyValue(sRedlineUndoEnd) >>= nCharEnd;
+            if(sType == sDelete)
+                nParagraphIdx++;
+
+            XMLTokenEnum eUndoType = XML_PARAGRAPH;
+            OUString sUndoType;
+            aAny = rPropSet->getPropertyValue(sRedlineUndoType);
+            aAny >>= sUndoType;
+
+            if( sUndoType == "text" )
+                eUndoType = XML_TEXT;
+            if(eUndoType == XML_PARAGRAPH)
+            {
+                rExport.AddAttribute(XML_NAMESPACE_C, XML_START, "/" + rtl::OUString::number(nParagraphIdx));
+                rExport.AddAttribute(XML_NAMESPACE_DC, XML_TYPE, XML_PARAGRAPH);
+            }
+            else
+            {
+                rExport.AddAttribute(XML_NAMESPACE_C, XML_START, "/" + rtl::OUString::number(nParagraphIdx) + "/" + rtl::OUString::number(nCharStart));
+                if( sType == sInsert || sType == sFormat )
+                    rExport.AddAttribute(XML_NAMESPACE_C, XML_END, "/" + rtl::OUString::number(nParagraphIdx) + "/" + rtl::OUString::number(nCharEnd));
+                rExport.AddAttribute(XML_NAMESPACE_DC, XML_TYPE, eUndoType);
+            }
+            SvXMLElementExport aChange(rExport, XML_NAMESPACE_TEXT,
+                                    ConvertTypeName(sType), true, true);
+
+            // get XText from the redline and export (if the XText exists)
+            aAny = rPropSet->getPropertyValue(sRedlineText);
+            Reference<XText> xText;
+            aAny >>= xText;
+            if (xText.is())
+            {
+                rExport.GetTextParagraphExport()->exportText(xText);
+                // default parameters: bProgress, bExportParagraph ???
+            }
+        }
+    }
+}
+
+void XMLRedlineExport::ExportChangeInline(
+    const Reference<XPropertySet> & rPropSet)
+{
+    // determine element name (depending on collapsed, start/end)
+    enum XMLTokenEnum eElement = XML_TOKEN_INVALID;
+    Any aAny = rPropSet->getPropertyValue(sIsCollapsed);
+    bool bCollapsed = *static_cast<sal_Bool const *>(aAny.getValue());
+    if (bCollapsed)
+    {
+        eElement = XML_CHANGE;
+    }
+    else
+    {
+        aAny = rPropSet->getPropertyValue(sIsStart);
+        const bool bStart = *static_cast<sal_Bool const *>(aAny.getValue());
+        eElement = bStart ? XML_CHANGE_START : XML_CHANGE_END;
+    }
+
+    if (XML_TOKEN_INVALID != eElement)
+    {
+        // we always need the ID
+        rExport.AddAttribute(XML_NAMESPACE_TEXT, XML_CHANGE_ID,
+                             GetRedlineID(rPropSet));
+
+        // export the element (no whitespace because we're in the text body)
+        SvXMLElementExport aChangeElem(rExport, XML_NAMESPACE_TEXT,
+                                       eElement, false, false);
+    }
+}
+
+
 void XMLRedlineExport::ExportChangedRegion(
     const Reference<XPropertySet> & rPropSet)
 {
+    // Redline-ID
+    rExport.AddAttributeIdLegacy(XML_NAMESPACE_TEXT, GetRedlineID(rPropSet));
+
     // merge-last-paragraph
     Any aAny = rPropSet->getPropertyValue(sMergeLastPara);
     if( ! *static_cast<sal_Bool const *>(aAny.getValue()) )
         rExport.AddAttribute(XML_NAMESPACE_TEXT, XML_MERGE_LAST_PARAGRAPH,
                              XML_FALSE);
 
+    // export change region element
+    SvXMLElementExport aChangedRegion(rExport, XML_NAMESPACE_TEXT,
+                                      XML_CHANGED_REGION, true, true);
+
+
     // scope for (first) change element
     {
         aAny = rPropSet->getPropertyValue(sRedlineType);
@@ -441,6 +547,30 @@ const OUString XMLRedlineExport::GetRedlineID(
     return sBuf.makeStringAndClear();
 }
 
+void XMLRedlineExport::ExportUndoChangeInfo(
+    const Reference<XPropertySet> & rPropSet, const sal_uInt32& rParaIdx)
+{
+    {
+        Any aAny = rPropSet->getPropertyValue(sRedlineAuthor);
+        OUString sAuthor;
+        aAny >>= sAuthor;
+        if (!sAuthor.isEmpty())
+        {
+            rExport.AddAttribute(XML_NAMESPACE_DC, XML_CREATOR, sAuthor);
+        }
+
+        aAny = rPropSet->getPropertyValue(sRedlineDateTime);
+        util::DateTime aDateTime;
+        aAny >>= aDateTime;
+        OUStringBuffer sBuf;
+        ::sax::Converter::convertDateTime(sBuf, aDateTime, nullptr);
+        rExport.AddAttribute(XML_NAMESPACE_DC, XML_DATE, sBuf.makeStringAndClear());
+
+        SvXMLElementExport aChange(rExport, XML_NAMESPACE_OFFICE,
+                                    XML_CHANGE, true, true);
+        ExportUndoChangeInline(rPropSet, rParaIdx);
+    }
+}
 
 void XMLRedlineExport::ExportChangeInfo(
     const Reference<XPropertySet> & rPropSet)
diff --git a/xmloff/source/text/XMLRedlineExport.hxx b/xmloff/source/text/XMLRedlineExport.hxx
index 1ece917..bac2901 100644
--- a/xmloff/source/text/XMLRedlineExport.hxx
+++ b/xmloff/source/text/XMLRedlineExport.hxx
@@ -103,6 +103,12 @@ public:
     ~XMLRedlineExport();
 
     /// export a change
+    void ExportUndoChange(
+        /// PropertySet of RedlinePortion
+        const css::uno::Reference<css::beans::XPropertySet> & rPropSet,
+        const sal_uInt32& rParaIdx,
+        bool bAutoStyle);
+
     void ExportChange(
         /// PropertySet of RedlinePortion
         const css::uno::Reference<css::beans::XPropertySet> & rPropSet,
@@ -145,6 +151,14 @@ public:
         bool bStart);
 
 private:
+    /// export the change mark contained in the text body
+    void ExportUndoChangeInline(
+        /// PropertySet of RedlinePortion
+        const css::uno::Reference<css::beans::XPropertySet> & rPropSet, const sal_uInt32& rParaIdx);
+
+    void ExportChangeInline(
+        /// PropertySet of RedlinePortion
+        const css::uno::Reference<css::beans::XPropertySet> & rPropSet);
 
     /// export the auto styles used in this change
     void ExportChangeAutoStyle(
@@ -162,6 +176,9 @@ private:
         const css::uno::Reference<css::beans::XPropertySet> & rPropSet);
 
     /// export an change-info element (from a PropertySet)
+    void ExportUndoChangeInfo(
+        const css::uno::Reference<css::beans::XPropertySet> & rPropSet, const sal_uInt32& rParaIdx);
+
     void ExportChangeInfo(
         const css::uno::Reference<css::beans::XPropertySet> & rPropSet);
 
diff --git a/xmloff/source/text/txtparae.cxx b/xmloff/source/text/txtparae.cxx
index d64165e..73bc313 100644
--- a/xmloff/source/text/txtparae.cxx
+++ b/xmloff/source/text/txtparae.cxx
@@ -1162,6 +1162,7 @@ XMLTextParagraphExport::XMLTextParagraphExport(
     pSectionExport( nullptr ),
     pIndexMarkExport( nullptr ),
     pRedlineExport( nullptr ),
+    nParaIdx(0),
     bProgress( false ),
     bBlock( false ),
     bOpenRuby( false ),
@@ -1628,6 +1629,67 @@ bool XMLTextParagraphExport::collectTextAutoStylesOptimized( bool bIsProgress )
     return true;
 }
 
+void XMLTextParagraphExport::exportUndoText(
+        const Reference < XText > & rText,
+        bool bAutoStyles,
+        bool bIsProgress,
+        bool bExportParagraph,
+        TextPNS eExtensionNS)
+{
+    if( bAutoStyles )
+        GetExport().GetShapeExport(); // make sure the graphics styles family
+                                      // is added
+    Reference < XEnumerationAccess > xEA( rText, UNO_QUERY );
+    Reference < XEnumeration > xParaEnum(xEA->createEnumeration());
+    Reference < XPropertySet > xPropertySet( rText, UNO_QUERY );
+    Reference < XTextSection > xBaseSection;
+
+    // #97718# footnotes don't supply paragraph enumerations in some cases
+    // This is always a bug, but at least we don't want to crash.
+    DBG_ASSERT( xParaEnum.is(), "We need a paragraph enumeration" );
+    if( ! xParaEnum.is() )
+        return;
+
+    bool bExportLevels = true;
+
+    if (xPropertySet.is())
+    {
+        Reference < XPropertySetInfo > xInfo ( xPropertySet->getPropertySetInfo() );
+
+        if( xInfo.is() )
+        {
+            if (xInfo->hasPropertyByName( sTextSection ))
+            {
+                xPropertySet->getPropertyValue(sTextSection) >>= xBaseSection ;
+            }
+
+/* #i35937#
+            // for applications that use the outliner we need to check if
+            // the current text object needs the level information exported
+            if( !bAutoStyles )
+            {
+                // fixme: move string to class member, couldn't do now because
+                //        of no incompatible build
+                OUString sHasLevels( "HasLevels" );
+                if (xInfo->hasPropertyByName( sHasLevels ) )
+                {
+                    xPropertySet->getPropertyValue(sHasLevels) >>= bExportLevels;
+                }
+            }
+*/
+        }
+    }
+
+    // #96530# Export redlines at start & end of XText before & after
+    // exporting the text content enumeration
+    if( !bAutoStyles && (pRedlineExport != nullptr) )
+        pRedlineExport->ExportStartOrEndRedline( xPropertySet, true );
+    exportUndoTextContentEnumeration( xParaEnum, bAutoStyles, xBaseSection,
+                                  bIsProgress, bExportParagraph, nullptr, bExportLevels, eExtensionNS );
+    if( !bAutoStyles && (pRedlineExport != nullptr) )
+        pRedlineExport->ExportStartOrEndRedline( xPropertySet, false );
+}
+
 void XMLTextParagraphExport::exportText(
         const Reference < XText > & rText,
         bool bAutoStyles,
@@ -1721,6 +1783,175 @@ void XMLTextParagraphExport::exportText(
         pRedlineExport->ExportStartOrEndRedline( xPropertySet, false );
 }
 
+bool XMLTextParagraphExport::exportUndoTextContentEnumeration(
+        const Reference < XEnumeration > & rContEnum,
+        bool bAutoStyles,
+        const Reference < XTextSection > & rBaseSection,
+        bool bIsProgress,
+        bool bExportParagraph,
+        const Reference < XPropertySet > *pRangePropSet,
+        bool bExportLevels, TextPNS eExtensionNS )
+{
+    DBG_ASSERT( rContEnum.is(), "No enumeration to export!" );
+    bool bHasMoreElements = rContEnum->hasMoreElements();
+    if( !bHasMoreElements )
+        return false;
+
+    XMLTextNumRuleInfo aPrevNumInfo;
+    XMLTextNumRuleInfo aNextNumInfo;
+
+    bool bHasContent = false;
+    Reference<XTextSection> xCurrentTextSection(rBaseSection);
+
+    MultiPropertySetHelper aPropSetHelper(
+                               bAutoStyles ? aParagraphPropertyNamesAuto :
+                                          aParagraphPropertyNames );
+
+    bool bHoldElement = false;
+    Reference < XTextContent > xTxtCntnt;
+    while( bHoldElement || bHasMoreElements )
+    {
+        if (bHoldElement)
+        {
+            bHoldElement = false;
+        }
+        else
+        {
+            xTxtCntnt.set(rContEnum->nextElement(), uno::UNO_QUERY);
+
+            aPropSetHelper.resetValues();
+
+        }
+
+        Reference<XServiceInfo> xServiceInfo( xTxtCntnt, UNO_QUERY );
+        if( xServiceInfo->supportsService( sParagraphService ) )
+        {
+            if( bExportLevels )
+            {
+                if( bAutoStyles )
+                {
+                    exportListAndSectionChange( xCurrentTextSection, xTxtCntnt,
+                                                aPrevNumInfo, aNextNumInfo,
+                                                bAutoStyles );
+                }
+                else
+                {
+                    /* Pass list auto style pool to <XMLTextNumRuleInfo> instance
+                       Pass info about request to export <text:number> element
+                       to <XMLTextNumRuleInfo> instance (#i69627#)
+                    */
+                    aNextNumInfo.Set( xTxtCntnt,
+                                      GetExport().writeOutlineStyleAsNormalListStyle(),
+                                      GetListAutoStylePool(),
+                                      GetExport().exportTextNumberElement() );
+
+                    exportListAndSectionChange( xCurrentTextSection, aPropSetHelper,
+                                                TEXT_SECTION, xTxtCntnt,
+                                                aPrevNumInfo, aNextNumInfo,
+                                                bAutoStyles );
+                }
+            }
+
+            // if we found a mute section: skip all section content
+            if (pSectionExport->IsMuteSection(xCurrentTextSection))
+            {
+                // Make sure headings are exported anyway.
+                if( !bAutoStyles )
+                    pSectionExport->ExportMasterDocHeadingDummies();
+
+                while (rContEnum->hasMoreElements() &&
+                       pSectionExport->IsInSection( xCurrentTextSection,
+                                                    xTxtCntnt, true ))
+                {
+                    xTxtCntnt.set(rContEnum->nextElement(), uno::UNO_QUERY);
+                    aPropSetHelper.resetValues();
+                    aNextNumInfo.Reset();
+                }
+                // the first non-mute element still needs to be processed
+                bHoldElement =
+                    ! pSectionExport->IsInSection( xCurrentTextSection,
+                                                   xTxtCntnt, false );
+            }
+            else
+            {
+                setParaIdx(getParaIdx() + 1);
+                exportUndoParagraph( xTxtCntnt, getParaIdx(), bAutoStyles, bIsProgress,
+                                 bExportParagraph, aPropSetHelper, eExtensionNS );
+            }
+            bHasContent = true;
+        }
+        else if( xServiceInfo->supportsService( sTableService ) )
+        {
+            if( !bAutoStyles )
+            {
+                aNextNumInfo.Reset();
+            }
+
+            exportListAndSectionChange( xCurrentTextSection, xTxtCntnt,
+                                        aPrevNumInfo, aNextNumInfo,
+                                        bAutoStyles );
+
+            if (! pSectionExport->IsMuteSection(xCurrentTextSection))
+            {
+                // export start + end redlines (for wholly redlined tables)
+                if ((! bAutoStyles) && (nullptr != pRedlineExport))
+                    pRedlineExport->ExportStartOrEndRedline(xTxtCntnt, true);
+
+                exportTable( xTxtCntnt, bAutoStyles, bIsProgress  );
+
+                if ((! bAutoStyles) && (nullptr != pRedlineExport))
+                    pRedlineExport->ExportStartOrEndRedline(xTxtCntnt, false);
+            }
+            else if( !bAutoStyles )
+            {
+                // Make sure headings are exported anyway.
+                pSectionExport->ExportMasterDocHeadingDummies();
+            }
+
+            bHasContent = true;
+        }
+        else if( xServiceInfo->supportsService( sTextFrameService ) )
+        {
+            exportTextFrame( xTxtCntnt, bAutoStyles, bIsProgress, true, pRangePropSet );
+        }
+        else if( xServiceInfo->supportsService( sTextGraphicService ) )
+        {
+            exportTextGraphic( xTxtCntnt, bAutoStyles, pRangePropSet );
+        }
+        else if( xServiceInfo->supportsService( sTextEmbeddedService ) )
+        {
+            exportTextEmbedded( xTxtCntnt, bAutoStyles, pRangePropSet );
+        }
+        else if( xServiceInfo->supportsService( sShapeService ) )
+        {
+            exportShape( xTxtCntnt, bAutoStyles, pRangePropSet );
+        }
+        else
+        {
+            DBG_ASSERT( !xTxtCntnt.is(), "unknown text content" );
+        }
+
+        if( !bAutoStyles )
+        {
+            aPrevNumInfo = aNextNumInfo;
+        }
+
+        bHasMoreElements = rContEnum->hasMoreElements();
+    }
+
+    if( bExportLevels && bHasContent && !bAutoStyles )
+    {
+        aNextNumInfo.Reset();
+
+        // close open lists and sections; no new styles
+        exportListAndSectionChange( xCurrentTextSection, rBaseSection,
+                                    aPrevNumInfo, aNextNumInfo,
+                                    bAutoStyles );
+    }
+
+    return true;
+}
+
 bool XMLTextParagraphExport::exportTextContentEnumeration(
         const Reference < XEnumeration > & rContEnum,
         bool bAutoStyles,
@@ -1811,8 +2042,10 @@ bool XMLTextParagraphExport::exportTextContentEnumeration(
                                                    xTxtCntnt, false );
             }
             else
+            {
                 exportParagraph( xTxtCntnt, bAutoStyles, bIsProgress,
-                                 bExportParagraph, aPropSetHelper, eExtensionNS );
+                                bExportParagraph, aPropSetHelper, eExtensionNS );
+            }
             bHasContent = true;
         }
         else if( xServiceInfo->supportsService( sTableService ) )
@@ -1887,8 +2120,8 @@ bool XMLTextParagraphExport::exportTextContentEnumeration(
     return true;
 }
 
-void XMLTextParagraphExport::exportParagraph(
-        const Reference < XTextContent > & rTextContent,
+void XMLTextParagraphExport::exportUndoParagraph(
+        const Reference < XTextContent > & rTextContent, const sal_uInt32& rParaIdx,
         bool bAutoStyles, bool bIsProgress, bool bExportParagraph,
         MultiPropertySetHelper& rPropSetHelper, TextPNS eExtensionNS)
 {
@@ -2125,28 +2358,329 @@ void XMLTextParagraphExport::exportParagraph(
     if( bAutoStyles )
     {
         if( bHasContentEnum )
-            exportTextContentEnumeration(
+            exportUndoTextContentEnumeration(
                                     xContentEnum, bAutoStyles, xSection,
                                     bIsProgress );
         if ( bHasPortions )
-            exportTextRangeEnumeration( xTextEnum, bAutoStyles, bIsProgress );
+            exportUndoTextRangeEnumeration( xTextEnum, rParaIdx, bAutoStyles, bIsProgress );
     }
     else
     {
         bool bPrevCharIsSpace = true;
         enum XMLTokenEnum eElem =
             0 < nOutlineLevel ? XML_H : XML_P;
-        SvXMLElementExport aElem( GetExport(), eExtensionNS == TextPNS::EXTENSION ? XML_NAMESPACE_LO_EXT : XML_NAMESPACE_TEXT, eElem,
-                                  true, false );
         if( bHasContentEnum )
-            bPrevCharIsSpace = !exportTextContentEnumeration(
+            bPrevCharIsSpace = !exportUndoTextContentEnumeration(
                                     xContentEnum, bAutoStyles, xSection,
                                     bIsProgress );
-        exportTextRangeEnumeration( xTextEnum, bAutoStyles, bIsProgress,
+        exportUndoTextRangeEnumeration( xTextEnum, rParaIdx, bAutoStyles, bIsProgress,
                                      bPrevCharIsSpace );
     }
 }
 
+void XMLTextParagraphExport::exportParagraph(
+        const Reference < XTextContent > & rTextContent,
+        bool bAutoStyles, bool bIsProgress, bool bExportParagraph,
+        MultiPropertySetHelper& rPropSetHelper, TextPNS eExtensionNS)
+{
+    sal_Int16 nOutlineLevel = -1;
+
+    if( bIsProgress )
+    {
+        ProgressBarHelper *pProgress = GetExport().GetProgressBarHelper();
+        pProgress->SetValue( pProgress->GetValue()+1 );
+    }
+
+    // get property set or multi property set and initialize helper
+    Reference<XMultiPropertySet> xMultiPropSet( rTextContent, UNO_QUERY );
+    Reference<XPropertySet> xPropSet( rTextContent, UNO_QUERY );
+
+    // check for supported properties
+    if( !rPropSetHelper.checkedProperties() )
+        rPropSetHelper.hasProperties( xPropSet->getPropertySetInfo() );
+
+//  if( xMultiPropSet.is() )
+//      rPropSetHelper.getValues( xMultiPropSet );
+//  else
+//      rPropSetHelper.getValues( xPropSet );
+
+    if( bExportParagraph )
+    {
+        if( bAutoStyles )
+        {
+            Add( XML_STYLE_FAMILY_TEXT_PARAGRAPH, rPropSetHelper, xPropSet );
+        }
+        else
+        {
+            // xml:id for RDF metadata
+            GetExport().AddAttributeXmlId(rTextContent);
+            GetExport().AddAttributesRDFa(rTextContent);
+
+            OUString sStyle;
+            if( rPropSetHelper.hasProperty( PARA_STYLE_NAME ) )
+            {
+                if( xMultiPropSet.is() )
+                    rPropSetHelper.getValue( PARA_STYLE_NAME,
+                                                    xMultiPropSet ) >>= sStyle;
+                else
+                    rPropSetHelper.getValue( PARA_STYLE_NAME,
+                                                    xPropSet ) >>= sStyle;
+            }
+
+            if( rTextContent.is() )
+            {
+                const OUString& rIdentifier = GetExport().getInterfaceToIdentifierMapper().getIdentifier( rTextContent );
+                if( !rIdentifier.isEmpty() )
+                {
+                    // FIXME: this is just temporary until EditEngine
+                    // paragraphs implement XMetadatable.
+                    // then that must be used and not the mapper, because
+                    // when both can be used we get two xml:id!
+                    uno::Reference<rdf::XMetadatable> const xMeta(rTextContent,
+                        uno::UNO_QUERY);
+                    OSL_ENSURE(!xMeta.is(), "paragraph that implements "
+                        "XMetadatable used in interfaceToIdentifierMapper?");
+                    GetExport().AddAttributeIdLegacy(XML_NAMESPACE_TEXT,
+                        rIdentifier);
+                }
+            }
+
+            OUString sAutoStyle( sStyle );
+            sAutoStyle = Find( XML_STYLE_FAMILY_TEXT_PARAGRAPH, xPropSet, sStyle );
+            if( !sAutoStyle.isEmpty() )
+                GetExport().AddAttribute( XML_NAMESPACE_TEXT, XML_STYLE_NAME,
+                              GetExport().EncodeStyleName( sAutoStyle ) );
+
+            if( rPropSetHelper.hasProperty( PARA_CONDITIONAL_STYLE_NAME ) )
+            {
+                OUString sCondStyle;
+                if( xMultiPropSet.is() )
+                    rPropSetHelper.getValue( PARA_CONDITIONAL_STYLE_NAME,
+                                                     xMultiPropSet ) >>= sCondStyle;
+                else
+                    rPropSetHelper.getValue( PARA_CONDITIONAL_STYLE_NAME,
+                                                     xPropSet ) >>= sCondStyle;
+                if( sCondStyle != sStyle )
+                {
+                    sCondStyle = Find( XML_STYLE_FAMILY_TEXT_PARAGRAPH, xPropSet,
+                                          sCondStyle );
+                    if( !sCondStyle.isEmpty() )
+                        GetExport().AddAttribute( XML_NAMESPACE_TEXT,
+                                                  XML_COND_STYLE_NAME,
+                              GetExport().EncodeStyleName( sCondStyle ) );
+                }
+            }
+
+            if( rPropSetHelper.hasProperty( PARA_OUTLINE_LEVEL ) )
+            {
+                if( xMultiPropSet.is() )
+                    rPropSetHelper.getValue( PARA_OUTLINE_LEVEL,
+                                                     xMultiPropSet ) >>= nOutlineLevel;
+                else
+                    rPropSetHelper.getValue( PARA_OUTLINE_LEVEL,
+                                                     xPropSet ) >>= nOutlineLevel;
+
+                if( 0 < nOutlineLevel )
+                {
+                    OUStringBuffer sTmp;
+                    sTmp.append( sal_Int32( nOutlineLevel) );
+                    GetExport().AddAttribute( XML_NAMESPACE_TEXT,
+                                              XML_OUTLINE_LEVEL,
+                                  sTmp.makeStringAndClear() );
+
+                    if( rPropSetHelper.hasProperty( NUMBERING_IS_NUMBER ) )
+                    {
+                        bool bIsNumber = false;
+                        if( xMultiPropSet.is() )
+                            rPropSetHelper.getValue(
+                                       NUMBERING_IS_NUMBER, xMultiPropSet ) >>= bIsNumber;
+                        else
+                            rPropSetHelper.getValue(
+                                       NUMBERING_IS_NUMBER, xPropSet ) >>= bIsNumber;
+
+                        OUString sListStyleName;
+                        if( xMultiPropSet.is() )
+                            rPropSetHelper.getValue(
+                                       PARA_NUMBERING_STYLENAME, xMultiPropSet ) >>= sListStyleName;
+                        else
+                            rPropSetHelper.getValue(
+                                       PARA_NUMBERING_STYLENAME, xPropSet ) >>= sListStyleName;
+
+                        bool bAssignedtoOutlineStyle = false;
+                        {
+                            Reference< XChapterNumberingSupplier > xCNSupplier( GetExport().GetModel(), UNO_QUERY );
+
+                            OUString sOutlineName;
+                            if (xCNSupplier.is())
+                            {
+                                Reference< XIndexReplace > xNumRule ( xCNSupplier->getChapterNumberingRules() );
+                                DBG_ASSERT( xNumRule.is(), "no chapter numbering rules" );
+
+                                if (xNumRule.is())
+                                {
+                                    Reference< XPropertySet > xNumRulePropSet( xNumRule, UNO_QUERY );
+                                    xNumRulePropSet->getPropertyValue(
+                                        "Name" ) >>= sOutlineName;
+                                    bAssignedtoOutlineStyle = ( sListStyleName == sOutlineName );
+                                }
+                            }
+                        }
+
+                        if( ! bIsNumber && bAssignedtoOutlineStyle )
+                            GetExport().AddAttribute( XML_NAMESPACE_TEXT,
+                                                      XML_IS_LIST_HEADER,
+                                                      XML_TRUE );
+                    }
+
+                    {
+                        bool bIsRestartNumbering = false;
+
+                        Reference< XPropertySetInfo >
+                        xPropSetInfo(xMultiPropSet.is() ?
+                                     xMultiPropSet->getPropertySetInfo():
+                                     xPropSet->getPropertySetInfo());
+
+                        if (xPropSetInfo->
+                            hasPropertyByName("ParaIsNumberingRestart"))
+                        {
+                            xPropSet->getPropertyValue("ParaIsNumberingRestart")
+                                >>= bIsRestartNumbering;
+                        }
+
+                        if (bIsRestartNumbering)
+                        {
+                            GetExport().AddAttribute(XML_NAMESPACE_TEXT,
+                                                     XML_RESTART_NUMBERING,
+                                                     XML_TRUE);
+
+                            if (xPropSetInfo->
+                                hasPropertyByName("NumberingStartValue"))
+                            {
+                                sal_Int32 nStartValue = 0;
+
+                                xPropSet->getPropertyValue("NumberingStartValue")
+                                    >>= nStartValue;
+
+                                OUStringBuffer sTmpStartValue;
+
+                                sTmpStartValue.append(nStartValue);
+
+                                GetExport().
+                                    AddAttribute(XML_NAMESPACE_TEXT,
+                                                 XML_START_VALUE,
+                                                 sTmpStartValue.
+                                                 makeStringAndClear());
+                            }
+                        }
+                    }
+                }
+            }
+        }
+    }
+
+    Reference < XEnumerationAccess > xEA( rTextContent, UNO_QUERY );
+    Reference < XEnumeration > xTextEnum;
+    xTextEnum = xEA->createEnumeration();
+    const bool bHasPortions = xTextEnum.is();
+
+    Reference < XEnumeration> xContentEnum;
+    Reference < XContentEnumerationAccess > xCEA( rTextContent, UNO_QUERY );
+    if( xCEA.is() )
+        xContentEnum.set(xCEA->createContentEnumeration( sTextContentService ));
+    const bool bHasContentEnum = xContentEnum.is() &&
+                                        xContentEnum->hasMoreElements();
+
+    Reference < XTextSection > xSection;
+    if( bHasContentEnum )
+    {
+        // For the auto styles, the multi property set helper is only used
+        // if hard attributes are existing. Therefore, it seems to be a better
+        // strategy to have the TextSection property separate, because otherwise
+        // we always retrieve the style names even if they are not required.
+        if( bAutoStyles )
+        {
+            if( xPropSet->getPropertySetInfo()->hasPropertyByName( sTextSection ) )
+            {
+                xSection.set(xPropSet->getPropertyValue( sTextSection ), uno::UNO_QUERY);
+            }
+        }
+        else
+        {
+            if( rPropSetHelper.hasProperty( TEXT_SECTION ) )
+            {
+                xSection.set(rPropSetHelper.getValue( TEXT_SECTION ), uno::UNO_QUERY);
+            }
+        }
+    }
+
+    if( bAutoStyles )
+    {
+        if( bHasContentEnum )
+            exportTextContentEnumeration(
+                                    xContentEnum, bAutoStyles, xSection,
+                                    bIsProgress );
+        if ( bHasPortions )
+            exportTextRangeEnumeration( xTextEnum, bAutoStyles, bIsProgress );
+    }
+    else
+    {
+        bool bPrevCharIsSpace = true;
+        enum XMLTokenEnum eElem =
+            0 < nOutlineLevel ? XML_H : XML_P;
+        SvXMLElementExport aElem( GetExport(), eExtensionNS == TextPNS::EXTENSION ? XML_NAMESPACE_LO_EXT : XML_NAMESPACE_TEXT, eElem,
+                                  true, false );
+        if( bHasContentEnum )
+            bPrevCharIsSpace = !exportTextContentEnumeration(
+                                    xContentEnum, bAutoStyles, xSection,
+                                    bIsProgress );
+        exportTextRangeEnumeration( xTextEnum, bAutoStyles, bIsProgress,
+                                     bPrevCharIsSpace );
+    }
+}
+
+void XMLTextParagraphExport::exportUndoTextRangeEnumeration(
+        const Reference < XEnumeration > & rTextEnum,
+        const sal_uInt32& rParaIdx,
+        bool bAutoStyles, bool bIsProgress,
+        bool bPrvChrIsSpc )
+{
+    static const char sMeta[] = "InContentMetadata";
+    static const char sFieldMarkName[] = "__FieldMark_";
+    static const char sAnnotation[] = "Annotation";
+    static const char sAnnotationEnd[] = "AnnotationEnd";
+
+    bool bPrevCharIsSpace = bPrvChrIsSpc;
+
+    /* This is  used for exporting to strict OpenDocument 1.2, in which case traditional
+     * bookmarks are used instead of fieldmarks. */
+    FieldmarkType openFieldMark = NONE;
+
+    while( rTextEnum->hasMoreElements() )
+    {
+        Reference<XPropertySet> xPropSet(rTextEnum->nextElement(), UNO_QUERY);
+        Reference < XTextRange > xTxtRange(xPropSet, uno::UNO_QUERY);
+        Reference<XPropertySetInfo> xPropInfo(xPropSet->getPropertySetInfo());
+
+        if (xPropInfo->hasPropertyByName(sTextPortionType))
+        {
+            OUString sType;
+            xPropSet->getPropertyValue(sTextPortionType) >>= sType;
+
+            if (sType.equals(sRedline))
+            {
+                if (nullptr != pRedlineExport)
+                    pRedlineExport->ExportUndoChange(xPropSet, rParaIdx, bAutoStyles);
+            }
+            else {
+                OSL_FAIL("unknown text portion type");
+            }
+        }
+    }
+
+// now that there are nested enumerations for meta(-field), this may be valid!
+//  DBG_ASSERT( !bOpenRuby, "Red Alert: Ruby still open!" );
+}
+
 void XMLTextParagraphExport::exportTextRangeEnumeration(
         const Reference < XEnumeration > & rTextEnum,
         bool bAutoStyles, bool bIsProgress,


More information about the Libreoffice-commits mailing list