sw: don't send LOK notifications about redlines during save

SwXMLWriter::Write_() sets redline flags to show insertion and hide
deletion, but it resets those flags before the function returns. So LOK
notifications for redline changes during save is not useful.

Change-Id: I4bf963bbe9c7003cbe85ea6c5538be733a3e3cdf
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/86363
Reviewed-by: Miklos Vajna <vmiklos@collabora.com>
Tested-by: Jenkins
diff --git a/sw/inc/doc.hxx b/sw/inc/doc.hxx
index c5075b2..f19ea9d 100644
--- a/sw/inc/doc.hxx
+++ b/sw/inc/doc.hxx
@@ -299,6 +299,7 @@ private:
                                               frames need deletion. */
    bool mbCopyIsMove            : 1;    //< TRUE: Copy is a hidden Move.
    bool mbInReading             : 1;    //< TRUE: Document is in the process of being read.
    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 mbUpdateTOX             : 1;    //< TRUE: After loading document, update TOX.
@@ -950,6 +951,9 @@ public:
    bool IsInReading() const                    { return mbInReading; }
    void SetInReading( bool bNew )              { mbInReading = bNew; }

    bool IsInWriting() const { return mbInWriting; }
    void SetInWriting(bool bNew) { mbInWriting = bNew; }

    bool IsInMailMerge() const                  { return mbInMailMerge; }
    void SetInMailMerge( bool bNew )            { mbInMailMerge = bNew; }

diff --git a/sw/qa/extras/tiledrendering/data/redline-notification-during-save.odt b/sw/qa/extras/tiledrendering/data/redline-notification-during-save.odt
new file mode 100644
index 0000000..df4c3068
--- /dev/null
+++ b/sw/qa/extras/tiledrendering/data/redline-notification-during-save.odt
Binary files differ
diff --git a/sw/qa/extras/tiledrendering/tiledrendering.cxx b/sw/qa/extras/tiledrendering/tiledrendering.cxx
index ba92741..8993111 100644
--- a/sw/qa/extras/tiledrendering/tiledrendering.cxx
+++ b/sw/qa/extras/tiledrendering/tiledrendering.cxx
@@ -12,6 +12,7 @@

#include <com/sun/star/frame/DispatchResultState.hpp>
#include <com/sun/star/frame/XDispatchResultListener.hpp>
#include <com/sun/star/frame/XStorable.hpp>
#include <swmodeltestbase.hxx>
#include <test/helper/transferable.hxx>
#include <LibreOfficeKit/LibreOfficeKitEnums.h>
@@ -121,6 +122,7 @@ public:
    void testSemiTransparent();
    void testAnchorTypes();
    void testLanguageStatus();
    void testRedlineNotificationDuringSave();

    CPPUNIT_TEST_SUITE(SwTiledRenderingTest);
    CPPUNIT_TEST(testRegisterCallback);
@@ -182,6 +184,7 @@ public:
    CPPUNIT_TEST(testSemiTransparent);
    CPPUNIT_TEST(testAnchorTypes);
    CPPUNIT_TEST(testLanguageStatus);
    CPPUNIT_TEST(testRedlineNotificationDuringSave);
    CPPUNIT_TEST_SUITE_END();

private:
@@ -2457,6 +2460,24 @@ void SwTiledRenderingTest::testLanguageStatus()
    CPPUNIT_ASSERT_EQUAL(OUString("English (USA);en-US"), aList[0]);
}

void SwTiledRenderingTest::testRedlineNotificationDuringSave()
{
    // Load a document with redlines which are hidden at a layout level.
    // It's an empty document, just settings.xml and content.xml are custom.
    comphelper::LibreOfficeKit::setActive();
    SwXTextDocument* pXTextDocument = createDoc("redline-notification-during-save.odt");
    SwWrtShell* pWrtShell = pXTextDocument->GetDocShell()->GetWrtShell();
    pWrtShell->GetSfxViewShell()->registerLibreOfficeKitViewCallback(&SwTiledRenderingTest::callback, this);

    // Save the document.
    utl::MediaDescriptor aMediaDescriptor;
    aMediaDescriptor["FilterName"] <<= OUString("writer8");
    uno::Reference<frame::XStorable> xStorable(mxComponent, uno::UNO_QUERY);
    // Without the accompanying fix in place, this test would have never returned due to an infinite
    // loop while sending not needed LOK notifications for redline changes during save.
    xStorable->storeToURL(maTempFile.GetURL(), aMediaDescriptor.getAsConstPropertyValueList());
}

CPPUNIT_TEST_SUITE_REGISTRATION(SwTiledRenderingTest);

CPPUNIT_PLUGIN_IMPLEMENT();
diff --git a/sw/source/core/doc/docnew.cxx b/sw/source/core/doc/docnew.cxx
index db14a1d..0e449883 100644
--- a/sw/source/core/doc/docnew.cxx
+++ b/sw/source/core/doc/docnew.cxx
@@ -240,6 +240,7 @@ SwDoc::SwDoc()
    mbDtor(false),
    mbCopyIsMove(false),
    mbInReading(false),
    mbInWriting(false),
    mbInMailMerge(false),
    mbInXMLImport(false),
    mbUpdateTOX(false),
diff --git a/sw/source/core/txtnode/ndtxt.cxx b/sw/source/core/txtnode/ndtxt.cxx
index 3a682cd..cc8c30a 100644
--- a/sw/source/core/txtnode/ndtxt.cxx
+++ b/sw/source/core/txtnode/ndtxt.cxx
@@ -1531,7 +1531,9 @@ void SwTextNode::Update(
    }

    // Inform LOK clients about change in position of redlines (if any)
    if (comphelper::LibreOfficeKit::isActive())
    // Don't emit notifications during save: redline flags are temporarily changed during save, but
    // it's not useful to let clients know about such changes.
    if (comphelper::LibreOfficeKit::isActive() && !GetDoc()->IsInWriting())
    {
        const SwRedlineTable& rTable = GetDoc()->getIDocumentRedlineAccess().GetRedlineTable();
        for (SwRedlineTable::size_type nRedlnPos = 0; nRedlnPos < rTable.size(); ++nRedlnPos)
diff --git a/sw/source/filter/basflt/shellio.cxx b/sw/source/filter/basflt/shellio.cxx
index 6c92434..d26214c 100644
--- a/sw/source/filter/basflt/shellio.cxx
+++ b/sw/source/filter/basflt/shellio.cxx
@@ -847,6 +847,7 @@ ErrCode SwWriter::Write( WriterRef const & rxWriter, const OUString* pRealFileNa

    auto xGuard = std::make_unique<PurgeGuard>(*pOutDoc);

    pOutDoc->SetInWriting(true);
    ErrCode nError = ERRCODE_NONE;
    if( pMedium )
        nError = rxWriter->Write( *pPam, *pMedium, pRealFileName );
@@ -854,6 +855,7 @@ ErrCode SwWriter::Write( WriterRef const & rxWriter, const OUString* pRealFileNa
        nError = rxWriter->Write( *pPam, *pStrm, pRealFileName );
    else if( xStg.is() )
        nError = rxWriter->Write( *pPam, xStg, pRealFileName );
    pOutDoc->SetInWriting(false);

    xGuard.reset();