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