Date: prev next · Thread: first prev next last
2011 Archives by date, by thread · List index


Hi guys,

        I attach a back-port of Lubos' patch from master fixing this for 3.4.5
- I'd love a 2nd review to get it included before Wed ;-)

        One slight annoyance is that what we export as docx with this patch is
re-imported with broken styles: ie. the comments are all strike-through
(by 3.4). However, that seems to be an un-related import bug, MSO/LibO
3.5 etc. all render the comments with the correct style. And, regardless
of the rendering, this avoids annoying comment data loss.

        HTH,

                Michael.

-- 
michael.meeks@suse.com  <><, Pseudo Engineer, itinerant idiot
From 9d6d74733ba66e6aa2264c549fac47699c8acf59 Mon Sep 17 00:00:00 2001
From: Michael Meeks <michael.meeks@suse.com>
Date: Tue, 13 Dec 2011 09:29:32 +0000
Subject: [PATCH] docx: Back-port Lubos' comment export work fdo#33463

---
 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


Context


Privacy Policy | Impressum (Legal Info) | Copyright information: Unless otherwise specified, all text and images on this website are licensed under the Creative Commons Attribution-Share Alike 3.0 License. This does not include the source code of LibreOffice, which is licensed under the Mozilla Public License (MPLv2). "LibreOffice" and "The Document Foundation" are registered trademarks of their corresponding registered owners or are in actual use as trademarks in one or more countries. Their respective logos and icons are also subject to international copyright laws. Use thereof is explained in our trademark policy.