[Libreoffice-commits] core.git: sw/inc sw/qa sw/source writerfilter/source

Caolán McNamara (via logerrit) logerrit at kemper.freedesktop.org
Tue Mar 24 19:32:51 UTC 2020


 sw/inc/doc.hxx                              |    3 +++
 sw/inc/unomap.hxx                           |    1 +
 sw/qa/core/data/ww6/pass/ofz21168-1.doc     |binary
 sw/source/core/doc/docnew.cxx               |    1 +
 sw/source/core/undo/undobj.cxx              |    4 ++--
 sw/source/core/unocore/unomap.cxx           |    1 +
 sw/source/filter/basflt/shellio.cxx         |    7 +++++++
 sw/source/uibase/uno/unotxdoc.cxx           |   12 ++++++++++++
 writerfilter/source/filter/RtfFilter.cxx    |   14 ++++++++++++++
 writerfilter/source/filter/WriterFilter.cxx |    5 +++++
 10 files changed, 46 insertions(+), 2 deletions(-)

New commits:
commit c4dab726caaa73be9f9c731312080143b0a0b89d
Author:     Caolán McNamara <caolanm at redhat.com>
AuthorDate: Thu Mar 12 12:43:10 2020 +0000
Commit:     Caolán McNamara <caolanm at redhat.com>
CommitDate: Tue Mar 24 20:32:16 2020 +0100

    ofz#21168 sw,writerfilter: limit writerfilter hack to writerfilter
    
    The problem is that at the end of WW8 import, a delete redline is
    inserted that ends up calling DeleteAndJoin from inside
    AppendRedline(). A fly is anchored AT_CHAR at (node 46, offset 0)
    and the deletion goes from (node 46, offset 0) to
    (node 48, offset 13) hence the special case check in
    IsDestroyFrameAnchoredAtChar() for the IsInReading() prevents it
    from being deleted, and then its anchor is still registered at the
    node 46 when it gets deleted.
    
    So try to restrict the WriterfilterHack to writerfilter, so it won't
    affect WW8 import.
    
    Unfortunately this is far less obvious than expected, because import can
    happen for creating a new file, in which case it's all done via UNO in
    writerfilter, or when inserting into an existing file, in which case
    SwReader::Read() is used.
    
    The SwDocShell's pMedium can't be used becuse in insert file case it
    will be the loaded file, not the inserted file.
    
    There isn't any obvious alternative to adding a silly UNO property for
    the writerfilter to use.
    
    Change-Id: Ia7fdc9bb1925202f6692ebee6e4b6b1fe50e5345
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/90384
    Tested-by: Jenkins
    Reviewed-by: Caolán McNamara <caolanm at redhat.com>

diff --git a/sw/inc/doc.hxx b/sw/inc/doc.hxx
index 6566cc56416e..f4cd14a1911e 100644
--- a/sw/inc/doc.hxx
+++ b/sw/inc/doc.hxx
@@ -303,6 +303,7 @@ private:
     bool mbInWriting : 1; //< TRUE: Document is in the process of being written.
     bool mbInMailMerge           : 1;    //< TRUE: Document is in the process of being written by mail merge.
     bool mbInXMLImport           : 1;    //< TRUE: During xml import, attribute portion building is not necessary.
+    bool mbInWriterfilterImport  : 1;    //< TRUE: writerfilter import (DOCX,RTF)
     bool mbUpdateTOX             : 1;    //< TRUE: After loading document, update TOX.
     bool mbInLoadAsynchron       : 1;    //< TRUE: Document is in the process of being loaded asynchronously.
     bool mbIsAutoFormatRedline   : 1;    //< TRUE: Redlines are recorded by Autoformat.
@@ -967,6 +968,8 @@ public:
 
     bool IsInXMLImport() const { return mbInXMLImport; }
     void SetInXMLImport( bool bNew ) { mbInXMLImport = bNew; }
+    bool IsInWriterfilterImport() const { return mbInWriterfilterImport; }
+    void SetInWriterfilterImport(bool const b) { mbInWriterfilterImport = b; }
 
     // Manage types of tables/indices
     sal_uInt16 GetTOXTypeCount( TOXTypes eTyp ) const;
diff --git a/sw/inc/unomap.hxx b/sw/inc/unomap.hxx
index 36f8766e0e03..caee6bc5c209 100644
--- a/sw/inc/unomap.hxx
+++ b/sw/inc/unomap.hxx
@@ -245,6 +245,7 @@ struct SfxItemPropertyMapEntry;
 #define WID_DOC_LOCK_UPDATES                    1016
 #define WID_DOC_HAS_VALID_SIGNATURES            1017
 #define WID_DOC_INTEROP_GRAB_BAG                1018
+#define WID_DOC_WRITERFILTER                    1019
 #define WID_DOC_BUILDID                         1024
 #define WID_DOC_ISTEMPLATEID                    1025
 #define WID_DOC_DEFAULT_PAGE_MODE               1069
diff --git a/sw/qa/core/data/ww6/pass/ofz21168-1.doc b/sw/qa/core/data/ww6/pass/ofz21168-1.doc
new file mode 100644
index 000000000000..3bafb1d36bf7
Binary files /dev/null and b/sw/qa/core/data/ww6/pass/ofz21168-1.doc differ
diff --git a/sw/source/core/doc/docnew.cxx b/sw/source/core/doc/docnew.cxx
index db01f3f00912..e4f38b44bbb0 100644
--- a/sw/source/core/doc/docnew.cxx
+++ b/sw/source/core/doc/docnew.cxx
@@ -245,6 +245,7 @@ SwDoc::SwDoc()
     mbInWriting(false),
     mbInMailMerge(false),
     mbInXMLImport(false),
+    mbInWriterfilterImport(false),
     mbUpdateTOX(false),
     mbInLoadAsynchron(false),
     mbIsAutoFormatRedline(false),
diff --git a/sw/source/core/undo/undobj.cxx b/sw/source/core/undo/undobj.cxx
index 125154579980..1a3c85d921ee 100644
--- a/sw/source/core/undo/undobj.cxx
+++ b/sw/source/core/undo/undobj.cxx
@@ -1558,7 +1558,7 @@ bool IsDestroyFrameAnchoredAtChar(SwPosition const & rAnchorPos,
     }
 
     if ((nDelContentType & DelContentType::WriterfilterHack)
-        && rAnchorPos.GetDoc()->IsInReading())
+        && rAnchorPos.GetDoc()->IsInWriterfilterImport())
     {   // FIXME hack for writerfilter RemoveLastParagraph() and MakeFlyAndMove(); can't test file format more specific?
         return (rStart < rAnchorPos) && (rAnchorPos < rEnd);
     }
@@ -1595,7 +1595,7 @@ bool IsSelectFrameAnchoredAtPara(SwPosition const & rAnchorPos,
     }
 
     if ((nDelContentType & DelContentType::WriterfilterHack)
-        && rAnchorPos.GetDoc()->IsInReading())
+        && rAnchorPos.GetDoc()->IsInWriterfilterImport())
     {   // FIXME hack for writerfilter RemoveLastParagraph() and MakeFlyAndMove(); can't test file format more specific?
         // but it MUST NOT be done during the SetRedlineFlags at the end of ODF
         // import, where the IsInXMLImport() cannot be checked because the
diff --git a/sw/source/core/unocore/unomap.cxx b/sw/source/core/unocore/unomap.cxx
index c2bdc1b34dbe..8da991f62451 100644
--- a/sw/source/core/unocore/unomap.cxx
+++ b/sw/source/core/unocore/unomap.cxx
@@ -628,6 +628,7 @@ const SfxItemPropertyMapEntry* SwUnoPropertyMapProvider::GetPropertyMapEntries(s
                     { OUString(UNO_NAME_APPLY_FORM_DESIGN_MODE),        WID_DOC_APPLY_FORM_DESIGN_MODE,     cppu::UnoType<bool>::get(), PROPERTY_NONE,   0},
                     { OUString(UNO_NAME_RUNTIME_UID), WID_DOC_RUNTIME_UID,  cppu::UnoType<OUString>::get(), PropertyAttribute::READONLY, 0},
                     { OUString(UNO_NAME_LOCK_UPDATES),        WID_DOC_LOCK_UPDATES,     cppu::UnoType<bool>::get(), PROPERTY_NONE,   0},
+                    { OUString("UndocumentedWriterfilterHack"), WID_DOC_WRITERFILTER,     cppu::UnoType<bool>::get(), PROPERTY_NONE,   0},
                     { OUString(UNO_NAME_HAS_VALID_SIGNATURES),  WID_DOC_HAS_VALID_SIGNATURES, cppu::UnoType<bool>::get(), PropertyAttribute::READONLY,   0},
                     { OUString(UNO_NAME_BUILDID), WID_DOC_BUILDID, cppu::UnoType<OUString>::get(), 0, 0},
                     { OUString(UNO_NAME_DOC_INTEROP_GRAB_BAG), WID_DOC_INTEROP_GRAB_BAG, cppu::UnoType< cppu::UnoSequenceType<css::beans::PropertyValue> >::get(), PROPERTY_NONE, 0 },
diff --git a/sw/source/filter/basflt/shellio.cxx b/sw/source/filter/basflt/shellio.cxx
index 85113a0f6404..bfde92363222 100644
--- a/sw/source/filter/basflt/shellio.cxx
+++ b/sw/source/filter/basflt/shellio.cxx
@@ -24,6 +24,7 @@
 #include <svl/fstathelper.hxx>
 #include <unotools/moduleoptions.hxx>
 #include <sfx2/docfile.hxx>
+#include <sfx2/docfilt.hxx>
 #include <editeng/lrspitem.hxx>
 #include <editeng/ulspitem.hxx>
 #include <editeng/boxitem.hxx>
@@ -34,6 +35,7 @@
 #include <fmtfsize.hxx>
 #include <fmtpdsc.hxx>
 #include <shellio.hxx>
+#include <iodetect.hxx>
 #include <doc.hxx>
 #include <IDocumentUndoRedo.hxx>
 #include <IDocumentSettingAccess.hxx>
@@ -103,6 +105,10 @@ ErrCode SwReader::Read( const Reader& rOptions )
 
     mxDoc->SetInReading( true );
     mxDoc->SetInXMLImport( dynamic_cast< XMLReader* >(po) !=  nullptr );
+    mxDoc->SetInWriterfilterImport(mpMedium && mpMedium->GetFilter()
+            && (mpMedium->GetFilter()->GetUserData() == FILTER_RTF
+                || mpMedium->GetFilter()->GetUserData() == sRtfWH
+                || mpMedium->GetFilter()->GetUserData() == FILTER_DOCX));
 
     SwPaM *pPam;
     if( mpCursor )
@@ -340,6 +346,7 @@ ErrCode SwReader::Read( const Reader& rOptions )
 
     mxDoc->SetInReading( false );
     mxDoc->SetInXMLImport( false );
+    mxDoc->SetInWriterfilterImport(false);
 
     mxDoc->InvalidateNumRules();
     mxDoc->UpdateNumRule();
diff --git a/sw/source/uibase/uno/unotxdoc.cxx b/sw/source/uibase/uno/unotxdoc.cxx
index 7e49697290e8..063af2f70ccd 100644
--- a/sw/source/uibase/uno/unotxdoc.cxx
+++ b/sw/source/uibase/uno/unotxdoc.cxx
@@ -1962,7 +1962,19 @@ void SwXTextDocument::setPropertyValue(const OUString& rPropertyName, const Any&
             SwDoc* pDoc = pDocShell->GetDoc();
             bool bBool (false);
             if( aValue >>= bBool )
+            {
               pDoc->SetInReading( bBool );
+            }
+        }
+        break;
+        case WID_DOC_WRITERFILTER:
+        {
+            SwDoc* pDoc = pDocShell->GetDoc();
+            bool bBool = {};
+            if (aValue >>= bBool)
+            { // HACK: writerfilter has to use API to set this :(
+              pDoc->SetInWriterfilterImport(bBool);
+            }
         }
         break;
         case WID_DOC_BUILDID:
diff --git a/writerfilter/source/filter/RtfFilter.cxx b/writerfilter/source/filter/RtfFilter.cxx
index 3197b8d77b3d..cf1b31aeb016 100644
--- a/writerfilter/source/filter/RtfFilter.cxx
+++ b/writerfilter/source/filter/RtfFilter.cxx
@@ -19,6 +19,7 @@
 
 #include <memory>
 
+#include <com/sun/star/beans/XPropertySet.hpp>
 #include <com/sun/star/document/XExporter.hpp>
 #include <com/sun/star/document/XFilter.hpp>
 #include <com/sun/star/document/XImporter.hpp>
@@ -95,6 +96,13 @@ sal_Bool RtfFilter::filter(const uno::Sequence<beans::PropertyValue>& rDescripto
     bool bResult(false);
     uno::Reference<task::XStatusIndicator> xStatusIndicator;
 
+    uno::Reference<beans::XPropertySet> xDocProps;
+    if (m_xDstDoc.is()) // not in cppunittest?
+    {
+        xDocProps.set(m_xDstDoc, uno::UNO_QUERY);
+        xDocProps->setPropertyValue("UndocumentedWriterfilterHack", uno::makeAny(true));
+    }
+
     try
     {
         utl::MediaDescriptor aMediaDesc(rDescriptor);
@@ -158,6 +166,12 @@ sal_Bool RtfFilter::filter(const uno::Sequence<beans::PropertyValue>& rDescripto
         TOOLS_INFO_EXCEPTION("writerfilter", "Exception caught");
     }
 
+    if (m_xDstDoc.is()) // not in cppunittest?
+    {
+        // note: pStream.clear calls RemoveLastParagraph()
+        xDocProps->setPropertyValue("UndocumentedWriterfilterHack", uno::makeAny(false));
+    }
+
     if (xStatusIndicator.is())
         xStatusIndicator->end();
     return bResult;
diff --git a/writerfilter/source/filter/WriterFilter.cxx b/writerfilter/source/filter/WriterFilter.cxx
index 7afc9c536637..a043dcb2764a 100644
--- a/writerfilter/source/filter/WriterFilter.cxx
+++ b/writerfilter/source/filter/WriterFilter.cxx
@@ -155,6 +155,8 @@ sal_Bool WriterFilter::filter(const uno::Sequence<beans::PropertyValue>& rDescri
     }
     if (m_xDstDoc.is())
     {
+        uno::Reference<beans::XPropertySet> const xDocProps(m_xDstDoc, uno::UNO_QUERY);
+        xDocProps->setPropertyValue("UndocumentedWriterfilterHack", uno::makeAny(true));
         utl::MediaDescriptor aMediaDesc(rDescriptor);
         bool bRepairStorage = aMediaDesc.getUnpackedValueOrDefault("RepairPackage", false);
         bool bSkipImages
@@ -280,6 +282,9 @@ sal_Bool WriterFilter::filter(const uno::Sequence<beans::PropertyValue>& rDescri
 
         pStream.clear();
 
+        // note: pStream.clear calls RemoveLastParagraph()
+        xDocProps->setPropertyValue("UndocumentedWriterfilterHack", uno::makeAny(false));
+
         return true;
     }
     return false;


More information about the Libreoffice-commits mailing list