[PATCH] docx: Back-port Lubos' comment export work fdo#33463

Michael Meeks michael.meeks at suse.com
Tue Dec 13 01:29:32 PST 2011


---
 sw/inc/docufld.hxx                           |    1 +
 sw/source/filter/ww8/attributeoutputbase.hxx |    3 +
 sw/source/filter/ww8/docxattributeoutput.cxx |   50 +++++++++++++++--
 sw/source/filter/ww8/docxattributeoutput.hxx |    8 +++
 sw/source/filter/ww8/docxexport.cxx          |   76 +++++++++++++++++++++++++-
 sw/source/filter/ww8/docxexport.hxx          |    5 ++
 sw/source/filter/ww8/wrtw8nds.cxx            |    2 +
 7 files changed, 138 insertions(+), 7 deletions(-)

diff --git a/sw/inc/docufld.hxx b/sw/inc/docufld.hxx
index 1818bec..3240aa2 100644
--- a/sw/inc/docufld.hxx
+++ b/sw/inc/docufld.hxx
@@ -532,6 +532,7 @@ public:
     virtual String			Expand() const;
     virtual SwField*		Copy() const;
 
+    inline const DateTime   GetDateTime() const             { return aDateTime; }
     inline const Date 		GetDate() const					{ return aDateTime.GetDate(); }
     inline const Time 		GetTime() const					{ return aDateTime.GetTime(); }
 
diff --git a/sw/source/filter/ww8/attributeoutputbase.hxx b/sw/source/filter/ww8/attributeoutputbase.hxx
index 84e58f7..92385fd 100644
--- a/sw/source/filter/ww8/attributeoutputbase.hxx
+++ b/sw/source/filter/ww8/attributeoutputbase.hxx
@@ -173,6 +173,9 @@ public:
     /// docx requires footnoteRef/endnoteRef tag at the beginning of each of them
     virtual void FootnoteEndnoteRefTag() {};
 
+    /// for docx w:commentReference
+    virtual void WritePostitFieldReference() {};
+
     /// Output text (inside a run).
     virtual void RunText( const String& rText, rtl_TextEncoding eCharSet ) = 0;
 
diff --git a/sw/source/filter/ww8/docxattributeoutput.cxx b/sw/source/filter/ww8/docxattributeoutput.cxx
index 693549c..5dfb281 100644
--- a/sw/source/filter/ww8/docxattributeoutput.cxx
+++ b/sw/source/filter/ww8/docxattributeoutput.cxx
@@ -548,7 +548,7 @@ void DocxAttributeOutput::EndRun()
     }
 
     // Write the hyperlink and toc fields starts
-    for ( std::vector<FieldInfos>::iterator pIt = m_Fields.begin(); pIt != m_Fields.end(); ++pIt )
+    for ( std::vector<FieldInfos>::iterator pIt = m_Fields.begin(); pIt != m_Fields.end(); )
     {
         // Add the fields starts for hyperlinks, TOCs and index marks
         if ( pIt->bOpen && !pIt->pField )
@@ -557,10 +557,11 @@ void DocxAttributeOutput::EndRun()
 
             // Remove the field if no end needs to be written
             if ( !pIt->bClose ) {
-                m_Fields.erase( pIt );
-                --pIt;
+                pIt = m_Fields.erase( pIt );
+                continue;
             }
         }
+        ++pIt;
     }
 
     DoWriteBookmarks( );
@@ -3212,9 +3213,40 @@ void DocxAttributeOutput::HiddenField( const SwField& /*rFld*/ )
     OSL_TRACE( "TODO DocxAttributeOutput::HiddenField()\n" );
 }
 
-void DocxAttributeOutput::PostitField( const SwField* /* pFld*/ )
+void DocxAttributeOutput::PostitField( const SwField* pFld )
 {
-    OSL_TRACE( "TODO DocxAttributeOutput::PostitField()\n" );
+    assert( dynamic_cast< const SwPostItField* >( pFld ));
+    m_postitFields.push_back( static_cast< const SwPostItField* >( pFld ));
+}
+
+void DocxAttributeOutput::WritePostitFieldReference()
+{
+    while( m_postitFieldsMaxId < m_postitFields.size())
+    {
+        OString idstr = OString::valueOf( sal_Int32( m_postitFieldsMaxId ));
+        m_pSerializer->singleElementNS( XML_w, XML_commentReference, FSNS( XML_w, XML_id ), idstr.getStr(), FSEND );
+        ++m_postitFieldsMaxId;
+    }
+}
+
+void DocxAttributeOutput::WritePostitFields()
+{
+    for( unsigned int i = 0;
+         i < m_postitFields.size();
+         ++i )
+    {
+        OString idstr = OString::valueOf( sal_Int32( i ));
+        const SwPostItField* f = m_postitFields[ i ];
+        m_pSerializer->startElementNS( XML_w, XML_comment, FSNS( XML_w, XML_id ), idstr.getStr(),
+            FSNS( XML_w, XML_author ), rtl::OUStringToOString( f->GetPar1(), RTL_TEXTENCODING_UTF8 ).getStr(),
+            FSNS( XML_w, XML_date ), impl_DateTimeToOString(f->GetDateTime()).getStr(), FSEND );
+        // Check for the text object existing, it seems that it can be NULL when saving a newly created
+        // comment without giving focus back to the main document. As GetTxt() is empty in that case as well,
+        // that is probably a bug in the Writer core.
+        if( f->GetTextObject() != NULL )
+            GetExport().WriteOutliner( *f->GetTextObject(), TXT_ATN );
+        m_pSerializer->endElementNS( XML_w, XML_comment );
+    }
 }
 
 bool DocxAttributeOutput::DropdownField( const SwField* pFld )
@@ -4118,7 +4150,8 @@ DocxAttributeOutput::DocxAttributeOutput( DocxExport &rExport, FSHelperPtr pSeri
       m_nTableDepth( 0 ),
       m_bParagraphOpened( false ),
       m_nColBreakStatus( COLBRK_NONE ),
-      m_pParentFrame( NULL )
+      m_pParentFrame( NULL ),
+      m_postitFieldsMaxId( 0 )
 {
 }
 
@@ -4154,4 +4187,9 @@ bool DocxAttributeOutput::HasEndnotes()
     return !m_pEndnotesList->isEmpty();
 }
 
+bool DocxAttributeOutput::HasPostitFields() const
+{
+    return !m_postitFields.empty();
+}
+
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/filter/ww8/docxattributeoutput.hxx b/sw/source/filter/ww8/docxattributeoutput.hxx
index 0875b46..3c80b8f 100644
--- a/sw/source/filter/ww8/docxattributeoutput.hxx
+++ b/sw/source/filter/ww8/docxattributeoutput.hxx
@@ -102,6 +102,8 @@ public:
 
     virtual void FootnoteEndnoteRefTag();
 
+    virtual void WritePostitFieldReference();
+
     /// Output text (inside a run).
     virtual void RunText( const String& rText, rtl_TextEncoding eCharSet = RTL_TEXTENCODING_UTF8 );
     
@@ -579,6 +581,9 @@ private:
 
     const sw::Frame *m_pParentFrame;
 
+    std::vector< const SwPostItField* > m_postitFields;
+    unsigned int m_postitFieldsMaxId;
+
 public:
     DocxAttributeOutput( DocxExport &rExport, ::sax_fastparser::FSHelperPtr pSerializer, oox::drawingml::DrawingML* pDrawingML );
 
@@ -602,6 +607,9 @@ public:
     
     /// Output the content of the footnotes.xml resp. endnotes.xml
     void FootnotesEndnotes( bool bFootnotes );
+
+    bool HasPostitFields() const;
+    void WritePostitFields();
 };
 
 #endif // _DOCXATTRIBUTEOUTPUT_HXX_
diff --git a/sw/source/filter/ww8/docxexport.cxx b/sw/source/filter/ww8/docxexport.cxx
index 33312da..0b29aea 100644
--- a/sw/source/filter/ww8/docxexport.cxx
+++ b/sw/source/filter/ww8/docxexport.cxx
@@ -53,6 +53,9 @@
 #include <frmfmt.hxx>
 #include <section.hxx>
 
+#include <editeng/editobj.hxx>
+#include <editeng/outlobj.hxx>
+
 #include <docary.hxx>
 #include <numrule.hxx>
 #include <charfmt.hxx>
@@ -337,7 +340,9 @@ void DocxExport::ExportDocument_Impl()
     WriteMainText();
 
     WriteFootnotesEndnotes();
-    
+
+    WritePostitFields();
+
     WriteNumbering();
 
     WriteFonts();
@@ -515,6 +520,26 @@ void DocxExport::WriteFootnotesEndnotes()
     }
 }
 
+void DocxExport::WritePostitFields()
+{
+    if ( m_pAttrOutput->HasPostitFields() )
+    {
+        m_pFilter->addRelation( m_pDocumentFS->getOutputStream(),
+                S( "http://schemas.openxmlformats.org/officeDocument/2006/relationships/comments" ),
+                S( "comments.xml" ) );
+
+        ::sax_fastparser::FSHelperPtr pPostitFS =
+            m_pFilter->openFragmentStreamWithSerializer( S( "word/comments.xml" ),
+                    S( "application/vnd.openxmlformats-officedocument.wordprocessingml.comments+xml" ) );
+
+        pPostitFS->startElementNS( XML_w, XML_comments, MainXmlNamespaces( pPostitFS ));
+        m_pAttrOutput->SetSerializer( pPostitFS );
+        m_pAttrOutput->WritePostitFields();
+        m_pAttrOutput->SetSerializer( m_pDocumentFS );
+        pPostitFS->endElementNS( XML_w, XML_comments );
+    }
+}
+
 void DocxExport::WriteNumbering()
 {
     if ( !pUsedNumTbl )
@@ -716,6 +741,55 @@ bool DocxExport::ignoreAttributeForStyles( sal_uInt16 nWhich ) const
     return MSWordExportBase::ignoreAttributeForStyles( nWhich );
 }
 
+void DocxExport::WriteOutliner(const OutlinerParaObject& rParaObj, sal_uInt8 nTyp)
+{
+    const EditTextObject& rEditObj = rParaObj.GetTextObject();
+    MSWord_SdrAttrIter aAttrIter( *this, rEditObj, nTyp );
+
+    sal_uInt16 nPara = rEditObj.GetParagraphCount();
+    for( sal_uInt16 n = 0; n < nPara; ++n )
+    {
+        if( n )
+            aAttrIter.NextPara( n );
+
+        AttrOutput().StartParagraph( ww8::WW8TableNodeInfo::Pointer_t());
+        rtl_TextEncoding eChrSet = aAttrIter.GetNodeCharSet();
+        String aStr( rEditObj.GetText( n ));
+        xub_StrLen nAktPos = 0;
+        xub_StrLen nEnd = aStr.Len();
+        do {
+            AttrOutput().StartRun( NULL );
+            xub_StrLen nNextAttr = aAttrIter.WhereNext();
+            rtl_TextEncoding eNextChrSet = aAttrIter.GetNextCharSet();
+
+            if( nNextAttr > nEnd )
+                nNextAttr = nEnd;
+
+            bool bTxtAtr = aAttrIter.IsTxtAttr( nAktPos );
+            if( !bTxtAtr )
+            {
+                if( nAktPos == 0 && nNextAttr - nAktPos == aStr.Len())
+                    AttrOutput().RunText( aStr, eChrSet );
+                else
+                {
+                    String tmp( aStr.Copy( nAktPos, nNextAttr - nAktPos ));
+                    AttrOutput().RunText( tmp, eChrSet );
+                }
+            }
+            AttrOutput().StartRunProperties();
+            aAttrIter.OutAttr( nAktPos );
+            AttrOutput().EndRunProperties( NULL );
+
+            nAktPos = nNextAttr;
+            eChrSet = eNextChrSet;
+            aAttrIter.NextPos();
+            AttrOutput().EndRun();
+        } while( nAktPos < nEnd );
+//        aAttrIter.OutParaAttr(false);
+        AttrOutput().EndParagraph( ww8::WW8TableNodeInfoInner::Pointer_t());
+    }
+}
+
 DocxExport::DocxExport( DocxExportFilter *pFilter, SwDoc *pDocument, SwPaM *pCurrentPam, SwPaM *pOriginalPam )
     : MSWordExportBase( pDocument, pCurrentPam, pOriginalPam ),
       m_pFilter( pFilter ),
diff --git a/sw/source/filter/ww8/docxexport.hxx b/sw/source/filter/ww8/docxexport.hxx
index ee84dcd..3eaec51 100644
--- a/sw/source/filter/ww8/docxexport.hxx
+++ b/sw/source/filter/ww8/docxexport.hxx
@@ -152,6 +152,8 @@ public:
     /// Returns the relationd id
     rtl::OString OutputChart( com::sun::star::uno::Reference< com::sun::star::frame::XModel >& xModel, sal_Int32 nCount );
 
+    void WriteOutliner(const OutlinerParaObject& rOutliner, sal_uInt8 nTyp);
+
 protected:
     /// Format-dependant part of the actual export.
     virtual void ExportDocument_Impl();
@@ -190,6 +192,9 @@ private:
     /// Write footnotes.xml and endnotes.xml.
     void WriteFootnotesEndnotes();
 
+    /// Write comments.xml
+    void WritePostitFields();
+
     /// Write the numbering table.
     virtual void WriteNumbering();
 
diff --git a/sw/source/filter/ww8/wrtw8nds.cxx b/sw/source/filter/ww8/wrtw8nds.cxx
index 02659bf..fae1dbc 100644
--- a/sw/source/filter/ww8/wrtw8nds.cxx
+++ b/sw/source/filter/ww8/wrtw8nds.cxx
@@ -2020,6 +2020,8 @@ void MSWordExportBase::OutputTextNode( const SwTxtNode& rNode )
             }
         }
 
+        AttrOutput().WritePostitFieldReference();
+
         AttrOutput().EndRun();
 
         nAktPos = nNextAttr;
-- 
1.7.3.4


--=-1e2ZUNZV2ieHb8yEIOlJ--



More information about the LibreOffice mailing list