sw/qa/extras/ooxmlexport/ooxmlexport.cxx     |   13 +-
 sw/source/filter/ww8/docxattributeoutput.cxx |  131 ++++++++++++++++++---------
 sw/source/filter/ww8/docxattributeoutput.hxx |   29 +++--
 sw/source/filter/ww8/docxexport.cxx          |   27 +++++
 sw/source/filter/ww8/docxexport.hxx          |    2 
 sw/source/filter/ww8/rtfexport.cxx           |    4 
 sw/source/filter/ww8/rtfexport.hxx           |    2 
 sw/source/filter/ww8/wrtw8nds.cxx            |  123 +++++++++++++++++++++++--
 sw/source/filter/ww8/wrtww8.cxx              |    4 
 sw/source/filter/ww8/wrtww8.hxx              |   21 +++-
 10 files changed, 285 insertions(+), 71 deletions(-)

New commits:
commit cda6438cc2c9be0032a80910f7e903dd7775838c
Author: Miklos Vajna <vmik...@collabora.co.uk>
Date:   Thu Jan 9 10:45:04 2014 +0100

    DOCX export of annotation marks
    
    Change-Id: I1d4fc68458fd50beccf4e149f74ecbdfc78ea77c

diff --git a/sw/qa/extras/ooxmlexport/ooxmlexport.cxx 
b/sw/qa/extras/ooxmlexport/ooxmlexport.cxx
index 0354aab..a584047 100644
--- a/sw/qa/extras/ooxmlexport/ooxmlexport.cxx
+++ b/sw/qa/extras/ooxmlexport/ooxmlexport.cxx
@@ -210,18 +210,16 @@ DECLARE_OOXMLEXPORT_TEST(defaultTabStopNotInStyles, 
"empty.odt")
 
 DECLARE_OOXMLEXPORT_TEST(testFdo38244, "fdo38244.docx")
 {
-#if 0
-    // FIXME port to AnnotationMarks
     /*
-     * Comments attached to a range was imported without the range, check for 
the fieldmark start/end positions.
+     * Comments attached to a range was imported without the range, check for 
the annotation mark start/end positions.
      *
      * oParas = ThisComponent.Text.createEnumeration
      * oPara = oParas.nextElement
      * oRuns = oPara.createEnumeration
      * oRun = oRuns.nextElement
-     * oRun = oRuns.nextElement 'TextFieldStart
+     * oRun = oRuns.nextElement 'Annotation
      * oRun = oRuns.nextElement
-     * oRun = oRuns.nextElement 'TextFieldEnd
+     * oRun = oRuns.nextElement 'AnnotationEnd
      * xray oRun.TextPortionType
      */
     uno::Reference<text::XTextDocument> xTextDocument(mxComponent, 
uno::UNO_QUERY);
@@ -231,10 +229,10 @@ DECLARE_OOXMLEXPORT_TEST(testFdo38244, "fdo38244.docx")
     uno::Reference<container::XEnumeration> xRunEnum = 
xRunEnumAccess->createEnumeration();
     xRunEnum->nextElement();
     uno::Reference<beans::XPropertySet> xPropertySet(xRunEnum->nextElement(), 
uno::UNO_QUERY);
-    CPPUNIT_ASSERT_EQUAL(OUString("TextFieldStart"), 
getProperty<OUString>(xPropertySet, "TextPortionType"));
+    CPPUNIT_ASSERT_EQUAL(OUString("Annotation"), 
getProperty<OUString>(xPropertySet, "TextPortionType"));
     xRunEnum->nextElement();
     xPropertySet.set(xRunEnum->nextElement(), uno::UNO_QUERY);
-    CPPUNIT_ASSERT_EQUAL(OUString("TextFieldEnd"), 
getProperty<OUString>(xPropertySet, "TextPortionType"));
+    CPPUNIT_ASSERT_EQUAL(OUString("AnnotationEnd"), 
getProperty<OUString>(xPropertySet, "TextPortionType"));
 
     /*
      * Initials were not imported.
@@ -272,7 +270,6 @@ DECLARE_OOXMLEXPORT_TEST(testFdo38244, "fdo38244.docx")
         bCaught = true;
     }
     CPPUNIT_ASSERT_EQUAL(true, bCaught);
-#endif
 }
 
 DECLARE_OOXMLEXPORT_TEST(testMathEscape, "math-escape.docx")
diff --git a/sw/source/filter/ww8/docxattributeoutput.cxx 
b/sw/source/filter/ww8/docxattributeoutput.cxx
index 93370ea..f992e5b 100644
--- a/sw/source/filter/ww8/docxattributeoutput.cxx
+++ b/sw/source/filter/ww8/docxattributeoutput.cxx
@@ -726,7 +726,7 @@ void DocxAttributeOutput::EndRun()
     StartRedline( m_pRedlineData );
 
     DoWriteBookmarks( );
-    WriteCommentRanges();
+    DoWriteAnnotationMarks( );
 
     m_pSerializer->startElementNS( XML_w, XML_r, FSEND );
     m_pSerializer->mergeTopMarks( sax_fastparser::MERGE_MARKS_PREPEND ); // 
merges with "postponed run start", see above
@@ -764,59 +764,87 @@ void DocxAttributeOutput::EndRun()
     }
 }
 
-void DocxAttributeOutput::WriteCommentRanges()
-{
-    if (m_bPostitStart)
-    {
-        m_bPostitStart = false;
-        OString idstr = OString::number( m_postitFieldsMaxId);
-        m_pSerializer->singleElementNS( XML_w, XML_commentRangeStart, FSNS( 
XML_w, XML_id ), idstr.getStr(), FSEND );
-    }
-    if (m_bPostitEnd)
-    {
-        m_bPostitEnd = false;
-        OString idstr = OString::number( m_postitFieldsMaxId);
-        m_pSerializer->singleElementNS( XML_w, XML_commentRangeEnd, FSNS( 
XML_w, XML_id ), idstr.getStr(), FSEND );
-    }
-}
-
 void DocxAttributeOutput::DoWriteBookmarks()
 {
     // Write the start bookmarks
-    for ( std::vector< OString >::const_iterator it = m_rMarksStart.begin(), 
end = m_rMarksStart.end();
+    for ( std::vector< OString >::const_iterator it = 
m_rBookmarksStart.begin(), end = m_rBookmarksStart.end();
           it != end; ++it )
     {
         const OString& rName = *it;
 
         // Output the bookmark
-        sal_uInt16 nId = m_nNextMarkId++;
-        m_rOpenedMarksIds[rName] = nId;
+        sal_uInt16 nId = m_nNextBookmarkId++;
+        m_rOpenedBookmarksIds[rName] = nId;
         m_pSerializer->singleElementNS( XML_w, XML_bookmarkStart,
             FSNS( XML_w, XML_id ), OString::number( nId ).getStr(  ),
             FSNS( XML_w, XML_name ), rName.getStr(),
             FSEND );
-        m_sLastOpenedMark = rName;
+        m_sLastOpenedBookmark = rName;
     }
-    m_rMarksStart.clear();
+    m_rBookmarksStart.clear();
 
     // export the end bookmarks
-    for ( std::vector< OString >::const_iterator it = m_rMarksEnd.begin(), end 
= m_rMarksEnd.end();
+    for ( std::vector< OString >::const_iterator it = m_rBookmarksEnd.begin(), 
end = m_rBookmarksEnd.end();
           it != end; ++it )
     {
         const OString& rName = *it;
 
         // Get the id of the bookmark
-        std::map< OString, sal_uInt16 >::iterator pPos = 
m_rOpenedMarksIds.find( rName );
-        if ( pPos != m_rOpenedMarksIds.end(  ) )
+        std::map< OString, sal_uInt16 >::iterator pPos = 
m_rOpenedBookmarksIds.find( rName );
+        if ( pPos != m_rOpenedBookmarksIds.end(  ) )
         {
             sal_uInt16 nId = ( *pPos ).second;
             m_pSerializer->singleElementNS( XML_w, XML_bookmarkEnd,
                 FSNS( XML_w, XML_id ), OString::number( nId ).getStr(  ),
                 FSEND );
-            m_rOpenedMarksIds.erase( rName );
+            m_rOpenedBookmarksIds.erase( rName );
         }
     }
-    m_rMarksEnd.clear();
+    m_rBookmarksEnd.clear();
+}
+
+void DocxAttributeOutput::DoWriteAnnotationMarks()
+{
+    // Write the start annotation marks
+    for ( std::vector< OString >::const_iterator it = 
m_rAnnotationMarksStart.begin(), end = m_rAnnotationMarksStart.end();
+          it != end; ++it )
+    {
+        const OString& rName = *it;
+
+        // Output the annotation mark
+        sal_uInt16 nId = m_nNextAnnotationMarkId++;
+        m_rOpenedAnnotationMarksIds[rName] = nId;
+        m_pSerializer->singleElementNS( XML_w, XML_commentRangeStart,
+            FSNS( XML_w, XML_id ), OString::number( nId ).getStr(  ),
+            FSEND );
+        m_sLastOpenedAnnotationMark = rName;
+    }
+    m_rAnnotationMarksStart.clear();
+
+    // export the end annotation marks
+    for ( std::vector< OString >::const_iterator it = 
m_rAnnotationMarksEnd.begin(), end = m_rAnnotationMarksEnd.end();
+          it != end; ++it )
+    {
+        const OString& rName = *it;
+
+        // Get the id of the annotation mark
+        std::map< OString, sal_uInt16 >::iterator pPos = 
m_rOpenedAnnotationMarksIds.find( rName );
+        if ( pPos != m_rOpenedAnnotationMarksIds.end(  ) )
+        {
+            sal_uInt16 nId = ( *pPos ).second;
+            m_pSerializer->singleElementNS( XML_w, XML_commentRangeEnd,
+                FSNS( XML_w, XML_id ), OString::number( nId ).getStr(  ),
+                FSEND );
+            m_rOpenedAnnotationMarksIds.erase( rName );
+
+            m_pSerializer->startElementNS(XML_w, XML_r, FSEND);
+            m_pSerializer->singleElementNS( XML_w, XML_commentReference, FSNS( 
XML_w, XML_id ),
+                                            OString::number( nId ).getStr(),
+                                            FSEND );
+            m_pSerializer->endElementNS(XML_w, XML_r);
+        }
+    }
+    m_rAnnotationMarksEnd.clear();
 }
 
 void DocxAttributeOutput::WriteFFData(  const FieldInfos& rInfos )
@@ -929,7 +957,7 @@ void DocxAttributeOutput::DoWriteCmd( const OUString& rCmd )
     if (sCmd.startsWith("SEQ"))
     {
         OUString sSeqName = msfilter::util::findQuotedText(sCmd, "SEQ ", 
'\\').trim();
-        m_aSeqMarksNames[sSeqName].push_back(m_sLastOpenedMark);
+        m_aSeqBookmarksNames[sSeqName].push_back(m_sLastOpenedBookmark);
     }
     // Write the Field command
     m_pSerializer->startElementNS( XML_w, XML_instrText, FSEND );
@@ -986,7 +1014,7 @@ void DocxAttributeOutput::EndField_Impl( FieldInfos& 
rInfos )
     if ( !aBkmName.isEmpty() )
     {
         m_pSerializer->singleElementNS( XML_w, XML_bookmarkStart,
-               FSNS( XML_w, XML_id ), OString::number( m_nNextMarkId ).getStr( 
),
+               FSNS( XML_w, XML_id ), OString::number( m_nNextBookmarkId 
).getStr( ),
                FSNS( XML_w, XML_name ), OUStringToOString( aBkmName, 
RTL_TEXTENCODING_UTF8 ).getStr( ),
                FSEND );
     }
@@ -1007,10 +1035,10 @@ void DocxAttributeOutput::EndField_Impl( FieldInfos& 
rInfos )
     if ( !aBkmName.isEmpty() )
     {
         m_pSerializer->singleElementNS( XML_w, XML_bookmarkEnd,
-               FSNS( XML_w, XML_id ), OString::number( m_nNextMarkId ).getStr( 
),
+               FSNS( XML_w, XML_id ), OString::number( m_nNextBookmarkId 
).getStr( ),
                FSEND );
 
-        m_nNextMarkId++;
+        m_nNextBookmarkId++;
     }
 
     // Write the Field end
@@ -1449,8 +1477,8 @@ bool DocxAttributeOutput::StartURL( const OUString& rUrl, 
const OUString& rTarge
                     OUString aSequenceName = OUString('"') + sMark.copy(0, 
nPos) + OUString('"');
                     // Extract <index>.
                     sal_uInt32 nIndex = sMark.copy(nPos + 1, sMark.getLength() 
- nPos - sizeof("|sequence")).toInt32();
-                    std::map<OUString, std::vector<OString> >::iterator it = 
m_aSeqMarksNames.find(aSequenceName);
-                    if (it != m_aSeqMarksNames.end())
+                    std::map<OUString, std::vector<OString> >::iterator it = 
m_aSeqBookmarksNames.find(aSequenceName);
+                    if (it != m_aSeqBookmarksNames.end())
                     {
                         std::vector<OString>& rNames = it->second;
                         if (rNames.size() > nIndex)
@@ -4618,19 +4646,23 @@ void DocxAttributeOutput::WritePostitFieldReference()
     while( m_postitFieldsMaxId < m_postitFields.size())
     {
         OString idstr = OString::number( m_postitFieldsMaxId);
-        m_pSerializer->singleElementNS( XML_w, XML_commentReference, FSNS( 
XML_w, XML_id ), idstr.getStr(), FSEND );
+
+        // In case this file is inside annotation marks, we want to write the
+        // comment reference after the annotation mark is closed, not here.
+        OString idname = 
OUStringToOString(m_postitFields[m_postitFieldsMaxId]->GetName(), 
RTL_TEXTENCODING_UTF8);
+        std::map< OString, sal_uInt16 >::iterator it = 
m_rOpenedAnnotationMarksIds.find( idname );
+        if ( it == m_rOpenedAnnotationMarksIds.end(  ) )
+            m_pSerializer->singleElementNS( XML_w, XML_commentReference, FSNS( 
XML_w, XML_id ), idstr.getStr(), FSEND );
         ++m_postitFieldsMaxId;
     }
 }
 
 void DocxAttributeOutput::WritePostitFieldStart()
 {
-    m_bPostitStart = true;
 }
 
 void DocxAttributeOutput::WritePostitFieldEnd()
 {
-    m_bPostitEnd = true;
 }
 
 void DocxAttributeOutput::WritePostitFields()
@@ -4750,14 +4782,32 @@ void DocxAttributeOutput::WriteBookmarks_Impl( 
std::vector< OUString >& rStarts,
     for ( std::vector< OUString >::const_iterator it = rStarts.begin(), end = 
rStarts.end(); it != end; ++it )
     {
         OString rName = OUStringToOString( *it, RTL_TEXTENCODING_UTF8 
).getStr( );
-        m_rMarksStart.push_back( rName );
+        m_rBookmarksStart.push_back( rName );
+    }
+    rStarts.clear();
+
+    for ( std::vector< OUString >::const_iterator it = rEnds.begin(), end = 
rEnds.end(); it != end; ++it )
+    {
+        OString rName = OUStringToOString( *it, RTL_TEXTENCODING_UTF8 
).getStr( );
+        m_rBookmarksEnd.push_back( rName );
+    }
+    rEnds.clear();
+}
+
+void DocxAttributeOutput::WriteAnnotationMarks_Impl( std::vector< OUString >& 
rStarts,
+        std::vector< OUString >& rEnds )
+{
+    for ( std::vector< OUString >::const_iterator it = rStarts.begin(), end = 
rStarts.end(); it != end; ++it )
+    {
+        OString rName = OUStringToOString( *it, RTL_TEXTENCODING_UTF8 
).getStr( );
+        m_rAnnotationMarksStart.push_back( rName );
     }
     rStarts.clear();
 
     for ( std::vector< OUString >::const_iterator it = rEnds.begin(), end = 
rEnds.end(); it != end; ++it )
     {
         OString rName = OUStringToOString( *it, RTL_TEXTENCODING_UTF8 
).getStr( );
-        m_rMarksEnd.push_back( rName );
+        m_rAnnotationMarksEnd.push_back( rName );
     }
     rEnds.clear();
 }
@@ -6157,9 +6207,8 @@ DocxAttributeOutput::DocxAttributeOutput( DocxExport 
&rExport, FSHelperPtr pSeri
       m_bOpenedSectPr( false ),
       m_bWritingHeaderFooter( false ),
       m_sFieldBkm( ),
-      m_nNextMarkId( 0 ),
-      m_bPostitStart(false),
-      m_bPostitEnd(false),
+      m_nNextBookmarkId( 0 ),
+      m_nNextAnnotationMarkId( 0 ),
       m_pTableWrt( NULL ),
       m_bParagraphOpened( false ),
       m_nColBreakStatus( COLBRK_NONE ),
diff --git a/sw/source/filter/ww8/docxattributeoutput.hxx 
b/sw/source/filter/ww8/docxattributeoutput.hxx
index 2ceab5a..69258b9 100644
--- a/sw/source/filter/ww8/docxattributeoutput.hxx
+++ b/sw/source/filter/ww8/docxattributeoutput.hxx
@@ -346,6 +346,7 @@ public:
     void WriteFormData_Impl( const ::sw::mark::IFieldmark& rFieldmark );
 
     void WriteBookmarks_Impl( std::vector< OUString >& rStarts, std::vector< 
OUString >& rEnds );
+    void WriteAnnotationMarks_Impl( std::vector< OUString >& rStarts, 
std::vector< OUString >& rEnds );
 
 private:
     /// Initialize the structures where we are going to collect some of the 
paragraph properties.
@@ -657,13 +658,13 @@ protected:
 private:
 
     void DoWriteBookmarks( );
+    void DoWriteAnnotationMarks( );
     void WritePostponedGraphic();
     void WritePostponedMath();
     void WritePostponedDiagram();
     void WritePostponedChart();
     void WritePostponedVMLDrawing();
     void WritePostponedDMLDrawing();
-    void WriteCommentRanges();
 
     void StartField_Impl( FieldInfos& rInfos, bool bWriteRun = sal_False );
     void DoWriteCmd( const OUString& rCmd );
@@ -706,26 +707,32 @@ private:
     /// Field data to remember in the text run
     std::vector< FieldInfos > m_Fields;
     OUString m_sFieldBkm;
-    sal_Int32 m_nNextMarkId;
+    sal_Int32 m_nNextBookmarkId;
+    sal_Int32 m_nNextAnnotationMarkId;
 
     /// Bookmarks to output
-    std::vector<OString> m_rMarksStart;
-    std::vector<OString> m_rMarksEnd;
+    std::vector<OString> m_rBookmarksStart;
+    std::vector<OString> m_rBookmarksEnd;
 
-    /// Is there a postit start to output?
-    bool m_bPostitStart;
-    /// Is there a postit end to output?
-    bool m_bPostitEnd;
+    /// Annotation marks to output
+    std::vector<OString> m_rAnnotationMarksStart;
+    std::vector<OString> m_rAnnotationMarksEnd;
 
     /// Maps of the bookmarks ids
-    std::map<OString, sal_uInt16> m_rOpenedMarksIds;
+    std::map<OString, sal_uInt16> m_rOpenedBookmarksIds;
 
     /// Name of the last opened bookmark.
-    OString m_sLastOpenedMark;
+    OString m_sLastOpenedBookmark;
+
+    /// Maps of the annotation marks ids
+    std::map<OString, sal_uInt16> m_rOpenedAnnotationMarksIds;
+
+    /// Name of the last opened annotation mark.
+    OString m_sLastOpenedAnnotationMark;
 
     /// If there are bookmarks around sequence fields, this map contains the
     /// names of these bookmarks for each sequence.
-    std::map<OUString, std::vector<OString> > m_aSeqMarksNames;
+    std::map<OUString, std::vector<OString> > m_aSeqBookmarksNames;
 
     /// The current table helper
     SwWriteTable *m_pTableWrt;
diff --git a/sw/source/filter/ww8/docxexport.cxx 
b/sw/source/filter/ww8/docxexport.cxx
index d8463a1..ece1c41 100644
--- a/sw/source/filter/ww8/docxexport.cxx
+++ b/sw/source/filter/ww8/docxexport.cxx
@@ -161,6 +161,33 @@ void DocxExport::AppendBookmark( const OUString& rName, 
bool /*bSkip*/ )
     m_pAttrOutput->WriteBookmarks_Impl( aStarts, aEnds );
 }
 
+void DocxExport::AppendAnnotationMarks( const SwTxtNode& rNode, sal_Int32 
nAktPos, sal_Int32 nLen )
+{
+    std::vector< OUString > aStarts;
+    std::vector< OUString > aEnds;
+
+    IMarkVector aMarks;
+    if ( GetAnnotationMarks( rNode, nAktPos, nAktPos + nLen, aMarks ) )
+    {
+        for ( IMarkVector::const_iterator it = aMarks.begin(), end = 
aMarks.end();
+              it != end; ++it )
+        {
+            IMark* pMark = (*it);
+
+            const sal_Int32 nStart = pMark->GetMarkStart().nContent.GetIndex();
+            const sal_Int32 nEnd = pMark->GetMarkEnd().nContent.GetIndex();
+
+            if ( nStart == nAktPos )
+                aStarts.push_back( pMark->GetName() );
+
+            if ( nEnd == nAktPos )
+                aEnds.push_back( pMark->GetName() );
+        }
+    }
+
+    m_pAttrOutput->WriteAnnotationMarks_Impl( aStarts, aEnds );
+}
+
 void DocxExport::ExportGrfBullet(const SwTxtNode&)
 {
     // Just collect the bullets for now, numbering.xml is not yet started.
diff --git a/sw/source/filter/ww8/docxexport.hxx 
b/sw/source/filter/ww8/docxexport.hxx
index eb7f804..abf22eb 100644
--- a/sw/source/filter/ww8/docxexport.hxx
+++ b/sw/source/filter/ww8/docxexport.hxx
@@ -118,6 +118,8 @@ public:
 
     virtual void AppendBookmark( const OUString& rName, bool bSkip = false );
 
+    virtual void AppendAnnotationMarks( const SwTxtNode& rNode, sal_Int32 
nAktPos, sal_Int32 nLen );
+
     virtual void ExportGrfBullet(const SwTxtNode&);
 
     /// Returns the relationd id
diff --git a/sw/source/filter/ww8/rtfexport.cxx 
b/sw/source/filter/ww8/rtfexport.cxx
index 59f55d9..1bc6494 100644
--- a/sw/source/filter/ww8/rtfexport.cxx
+++ b/sw/source/filter/ww8/rtfexport.cxx
@@ -163,6 +163,10 @@ void RtfExport::AppendBookmark( const OUString& rName, 
bool /*bSkip*/ )
     m_pAttrOutput->WriteBookmarks_Impl(aStarts, aEnds);
 }
 
+void RtfExport::AppendAnnotationMarks( const SwTxtNode& /*rNode*/, sal_Int32 
/*nAktPos*/, sal_Int32 /*nLen*/ )
+{
+}
+
 //For i120928,to export graphic of bullet for RTF filter
 void RtfExport::ExportGrfBullet(const SwTxtNode&)
 {
diff --git a/sw/source/filter/ww8/rtfexport.hxx 
b/sw/source/filter/ww8/rtfexport.hxx
index 7e429af..e776f2e 100644
--- a/sw/source/filter/ww8/rtfexport.hxx
+++ b/sw/source/filter/ww8/rtfexport.hxx
@@ -69,6 +69,8 @@ public:
 
     virtual void AppendBookmark( const OUString& rName, bool bSkip = false );
 
+    virtual void AppendAnnotationMarks( const SwTxtNode& rNode, sal_Int32 
nAktPos, sal_Int32 nLen );
+
     //For i120928,add an interface to export graphic of bullet
     virtual void ExportGrfBullet(const SwTxtNode& rNd);
 
diff --git a/sw/source/filter/ww8/wrtw8nds.cxx 
b/sw/source/filter/ww8/wrtw8nds.cxx
index 0ef766e..9d4818b 100644
--- a/sw/source/filter/ww8/wrtw8nds.cxx
+++ b/sw/source/filter/ww8/wrtw8nds.cxx
@@ -1660,13 +1660,16 @@ sal_Int32 MSWordExportBase::GetNextPos( SwWW8AttrIter* 
aAttrIter, const SwTxtNod
     // Get the bookmarks for the normal run
     const sal_Int32 nNextPos = aAttrIter->WhereNext();
     sal_Int32 nNextBookmark = nNextPos;
+    sal_Int32 nNextAnnotationMark = nNextPos;
 
     if( nNextBookmark > nAktPos ) //no need to search for bookmarks otherwise 
(checked in UpdatePosition())
     {
         GetSortedBookmarks( rNode, nAktPos, nNextBookmark - nAktPos );
         NearestBookmark( nNextBookmark, nAktPos, false );
+        GetSortedAnnotationMarks( rNode, nAktPos, nNextAnnotationMark - 
nAktPos );
+        NearestAnnotationMark( nNextAnnotationMark, nAktPos, false );
     }
-    return std::min( nNextPos, nNextBookmark );
+    return std::min( nNextPos, std::min( nNextBookmark, nNextAnnotationMark ) 
);
 }
 
 void MSWordExportBase::UpdatePosition( SwWW8AttrIter* aAttrIter, sal_Int32 
nAktPos, sal_Int32 /*nEnd*/ )
@@ -1716,6 +1719,37 @@ bool MSWordExportBase::GetBookmarks( const SwTxtNode& 
rNd, sal_Int32 nStt,
     return ( rArr.size() > 0 );
 }
 
+bool MSWordExportBase::GetAnnotationMarks( const SwTxtNode& rNd, sal_Int32 
nStt,
+                    sal_Int32 nEnd, IMarkVector& rArr )
+{
+    IDocumentMarkAccess* const pMarkAccess = pDoc->getIDocumentMarkAccess();
+    sal_uLong nNd = rNd.GetIndex( );
+
+    const sal_Int32 nMarks = pMarkAccess->getAnnotationMarksCount();
+    for ( sal_Int32 i = 0; i < nMarks; i++ )
+    {
+        IMark* pMark = ( pMarkAccess->getAnnotationMarksBegin() + i )->get();
+
+        // Only keep the bookmarks starting or ending in this node
+        if ( pMark->GetMarkStart().nNode == nNd ||
+             pMark->GetMarkEnd().nNode == nNd )
+        {
+            const sal_Int32 nBStart = 
pMark->GetMarkStart().nContent.GetIndex();
+            const sal_Int32 nBEnd = pMark->GetMarkEnd().nContent.GetIndex();
+
+            // Keep only the bookmars starting or ending in the snippet
+            bool bIsStartOk = ( pMark->GetMarkStart().nNode == nNd ) && ( 
nBStart >= nStt ) && ( nBStart <= nEnd );
+            bool bIsEndOk = ( pMark->GetMarkEnd().nNode == nNd ) && ( nBEnd >= 
nStt ) && ( nBEnd <= nEnd );
+
+            if ( bIsStartOk || bIsEndOk )
+            {
+                rArr.push_back( pMark );
+            }
+        }
+    }
+    return ( rArr.size() > 0 );
+}
+
 class CompareMarksEnd : public std::binary_function < const IMark *, const 
IMark *, bool >
 {
 public:
@@ -1732,9 +1766,9 @@ bool MSWordExportBase::NearestBookmark( sal_Int32& 
rNearest, const sal_Int32 nAk
 {
     bool bHasBookmark = false;
 
-    if ( !m_rSortedMarksStart.empty() )
+    if ( !m_rSortedBookmarksStart.empty() )
     {
-        IMark* pMarkStart = m_rSortedMarksStart.front();
+        IMark* pMarkStart = m_rSortedBookmarksStart.front();
         const sal_Int32 nNext = pMarkStart->GetMarkStart().nContent.GetIndex();
         if( !bNextPositionOnly || (nNext > nAktPos ))
         {
@@ -1743,9 +1777,9 @@ bool MSWordExportBase::NearestBookmark( sal_Int32& 
rNearest, const sal_Int32 nAk
         }
     }
 
-    if ( !m_rSortedMarksEnd.empty() )
+    if ( !m_rSortedBookmarksEnd.empty() )
     {
-        IMark* pMarkEnd = m_rSortedMarksEnd[0];
+        IMark* pMarkEnd = m_rSortedBookmarksEnd[0];
         const sal_Int32 nNext = pMarkEnd->GetMarkEnd().nContent.GetIndex();
         if( !bNextPositionOnly || nNext > nAktPos )
         {
@@ -1760,6 +1794,74 @@ bool MSWordExportBase::NearestBookmark( sal_Int32& 
rNearest, const sal_Int32 nAk
     return bHasBookmark;
 }
 
+bool MSWordExportBase::NearestAnnotationMark( sal_Int32& rNearest, const 
sal_Int32 nAktPos, bool bNextPositionOnly )
+{
+    bool bHasAnnotationMark = false;
+
+    if ( !m_rSortedAnnotationMarksStart.empty() )
+    {
+        IMark* pMarkStart = m_rSortedAnnotationMarksStart.front();
+        const sal_Int32 nNext = pMarkStart->GetMarkStart().nContent.GetIndex();
+        if( !bNextPositionOnly || (nNext > nAktPos ))
+        {
+            rNearest = nNext;
+            bHasAnnotationMark = true;
+        }
+    }
+
+    if ( !m_rSortedAnnotationMarksEnd.empty() )
+    {
+        IMark* pMarkEnd = m_rSortedAnnotationMarksEnd[0];
+        const sal_Int32 nNext = pMarkEnd->GetMarkEnd().nContent.GetIndex();
+        if( !bNextPositionOnly || nNext > nAktPos )
+        {
+            if ( !bHasAnnotationMark )
+                rNearest = nNext;
+            else
+                rNearest = std::min( rNearest, nNext );
+            bHasAnnotationMark = true;
+        }
+    }
+
+    return bHasAnnotationMark;
+}
+
+void MSWordExportBase::GetSortedAnnotationMarks( const SwTxtNode& rNode, 
sal_Int32 nAktPos, sal_Int32 nLen )
+{
+    IMarkVector aMarksStart;
+    if ( GetAnnotationMarks( rNode, nAktPos, nAktPos + nLen, aMarksStart ) )
+    {
+        IMarkVector aSortedEnd;
+        IMarkVector aSortedStart;
+        for ( IMarkVector::const_iterator it = aMarksStart.begin(), end = 
aMarksStart.end();
+              it != end; ++it )
+        {
+            IMark* pMark = (*it);
+
+            // Remove the positions egals to the current pos
+            const sal_Int32 nStart = pMark->GetMarkStart().nContent.GetIndex();
+            const sal_Int32 nEnd = pMark->GetMarkEnd().nContent.GetIndex();
+
+            if ( nStart > nAktPos && ( pMark->GetMarkStart().nNode == 
rNode.GetIndex()) )
+                aSortedStart.push_back( pMark );
+
+            if ( nEnd > nAktPos && nEnd <= ( nAktPos + nLen ) && 
(pMark->GetMarkEnd().nNode == rNode.GetIndex()) )
+                aSortedEnd.push_back( pMark );
+        }
+
+        // Sort the bookmarks by end position
+        std::sort( aSortedEnd.begin(), aSortedEnd.end(), CompareMarksEnd() );
+
+        m_rSortedAnnotationMarksStart.swap( aSortedStart );
+        m_rSortedAnnotationMarksEnd.swap( aSortedEnd );
+    }
+    else
+    {
+        m_rSortedAnnotationMarksStart.clear( );
+        m_rSortedAnnotationMarksEnd.clear( );
+    }
+}
+
 void MSWordExportBase::GetSortedBookmarks( const SwTxtNode& rNode, sal_Int32 
nAktPos, sal_Int32 nLen )
 {
     IMarkVector aMarksStart;
@@ -1786,13 +1888,13 @@ void MSWordExportBase::GetSortedBookmarks( const 
SwTxtNode& rNode, sal_Int32 nAk
         // Sort the bookmarks by end position
         std::sort( aSortedEnd.begin(), aSortedEnd.end(), CompareMarksEnd() );
 
-        m_rSortedMarksStart.swap( aSortedStart );
-        m_rSortedMarksEnd.swap( aSortedEnd );
+        m_rSortedBookmarksStart.swap( aSortedStart );
+        m_rSortedBookmarksEnd.swap( aSortedEnd );
     }
     else
     {
-        m_rSortedMarksStart.clear( );
-        m_rSortedMarksEnd.clear( );
+        m_rSortedBookmarksStart.clear( );
+        m_rSortedBookmarksEnd.clear( );
     }
 }
 
@@ -1890,6 +1992,7 @@ void MSWordExportBase::OutputTextNode( const SwTxtNode& 
rNode )
         // Append bookmarks in this range after flys, exclusive of final
         // position of this range
         AppendBookmarks( rNode, nAktPos, nNextAttr - nAktPos );
+        AppendAnnotationMarks( rNode, nAktPos, nNextAttr - nAktPos );
         bool bTxtAtr = aAttrIter.IsTxtAttr( nAktPos );
         nOpenAttrWithRange += aAttrIter.OutAttrWithRange(nAktPos);
 
@@ -2040,6 +2143,7 @@ void MSWordExportBase::OutputTextNode( const SwTxtNode& 
rNode )
                     aAttrIter.OutFlys( nEnd );
                     // insert final bookmarks if any before CR and after flys
                     AppendBookmarks( rNode, nEnd, 1 );
+                    AppendAnnotationMarks( rNode, nEnd, 1 );
                     if ( pTOXSect )
                     {
                         m_aCurrentCharPropStarts.pop();
@@ -2088,6 +2192,7 @@ void MSWordExportBase::OutputTextNode( const SwTxtNode& 
rNode )
                 aAttrIter.OutFlys( nEnd );
                 // insert final bookmarks if any before CR and after flys
                 AppendBookmarks( rNode, nEnd, 1 );
+                AppendAnnotationMarks( rNode, nEnd, 1 );
                 WriteCR( pTextNodeInfoInner );
                 // #i120928 - position of the bullet's graphic is at end of doc
                 if (bLastCR && (!bExported))
diff --git a/sw/source/filter/ww8/wrtww8.cxx b/sw/source/filter/ww8/wrtww8.cxx
index 6fca2d93..d8a3d92 100644
--- a/sw/source/filter/ww8/wrtww8.cxx
+++ b/sw/source/filter/ww8/wrtww8.cxx
@@ -1387,6 +1387,10 @@ void WW8Export::AppendBookmarks( const SwTxtNode& rNd, 
sal_Int32 nAktPos, sal_In
     }
 }
 
+void WW8Export::AppendAnnotationMarks( const SwTxtNode& /*rNd*/, sal_Int32 
/*nAktPos*/, sal_Int32 /*nLen*/ )
+{
+}
+
 void WW8Export::MoveFieldMarks(WW8_CP nFrom, WW8_CP nTo)
 {
     pBkmks->MoveFieldMarks(nFrom, nTo);
diff --git a/sw/source/filter/ww8/wrtww8.hxx b/sw/source/filter/ww8/wrtww8.hxx
index fb21b25..c40f00c 100644
--- a/sw/source/filter/ww8/wrtww8.hxx
+++ b/sw/source/filter/ww8/wrtww8.hxx
@@ -548,8 +548,10 @@ public:
 
     /// Used to split the runs according to the bookmarks start and ends
     typedef std::vector< ::sw::mark::IMark* > IMarkVector;
-    IMarkVector m_rSortedMarksStart;
-    IMarkVector m_rSortedMarksEnd;
+    IMarkVector m_rSortedBookmarksStart;
+    IMarkVector m_rSortedBookmarksEnd;
+    IMarkVector m_rSortedAnnotationMarksStart;
+    IMarkVector m_rSortedAnnotationMarksEnd;
 
 public:
     /// The main function to export the document.
@@ -647,6 +649,9 @@ public:
     virtual void AppendBookmarks( const SwTxtNode& rNd, sal_Int32 nAktPos, 
sal_Int32 nLen ) = 0;
 
     virtual void AppendBookmark( const OUString& rName, bool bSkip = false ) = 
0;
+
+    virtual void AppendAnnotationMarks( const SwTxtNode& rNd, sal_Int32 
nAktPos, sal_Int32 nLen ) = 0;
+
     //For i120928,add this interface to export graphic of bullet
     virtual void ExportGrfBullet(const SwTxtNode& rNd) = 0;
 
@@ -822,6 +827,16 @@ protected:
     bool GetBookmarks( const SwTxtNode& rNd, sal_Int32 nStt, sal_Int32 nEnd,
             IMarkVector& rArr );
 
+    /// Find the nearest annotation mark from the current position.
+    ///
+    /// Returns false when there is no annotation mark.
+    bool NearestAnnotationMark( sal_Int32& rNearest, const sal_Int32 nAktPos, 
bool bNextPositionOnly );
+
+    void GetSortedAnnotationMarks( const SwTxtNode& rNd, sal_Int32 nAktPos, 
sal_Int32 nLen );
+
+    bool GetAnnotationMarks( const SwTxtNode& rNd, sal_Int32 nStt, sal_Int32 
nEnd,
+            IMarkVector& rArr );
+
     const NfKeywordTable & GetNfKeywordTable();
 
     /// Populates m_vecBulletPic with all the bullet graphics used by 
numberings.
@@ -1017,6 +1032,8 @@ public:
     virtual void AppendBookmarks( const SwTxtNode& rNd, sal_Int32 nAktPos, 
sal_Int32 nLen );
     virtual void AppendBookmark( const OUString& rName, bool bSkip = false );
 
+    virtual void AppendAnnotationMarks( const SwTxtNode& rNd, sal_Int32 
nAktPos, sal_Int32 nLen );
+
     virtual void ExportGrfBullet(const SwTxtNode& rNd);
     void OutGrfBullets(const sw::Frame &rFrame);
 
_______________________________________________
Libreoffice-commits mailing list
libreoffice-comm...@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/libreoffice-commits

Reply via email to