tdf#97103 sw: fix restoring of SetRedlineMode on DOCX/RTF export

In order to prevent ~SwIndexReg asserts, this was changed to restore
the redline mode not in MSWordExportBase::ExportDocument() but in
SwWriter::Write().  Unfortunately only the DOC export actually uses
SwWriter::Write(), so fix the original problem differently by moving the
cursors onto a EndNode.

The m_pCurPam will be deleted anyway, and the m_pOrigPam usually also
will be, and in the case it isn't deleted i hope it's not important :)

(regression from 0b037361b890a83a735186b98d5a3cef124027f4)

Change-Id: Ib3d0cc32862256fdc4363b6035c190cbbcfe5df3
diff --git a/sw/CppunitTest_sw_globalfilter.mk b/sw/CppunitTest_sw_globalfilter.mk
index 6650266..8c48b49 100644
--- a/sw/CppunitTest_sw_globalfilter.mk
+++ b/sw/CppunitTest_sw_globalfilter.mk
@@ -50,41 +50,7 @@ $(eval $(call gb_CppunitTest_use_api,sw_globalfilter,\
$(eval $(call gb_CppunitTest_use_ure,sw_globalfilter))
$(eval $(call gb_CppunitTest_use_vcl,sw_globalfilter))

$(eval $(call gb_CppunitTest_use_components,sw_globalfilter,\
	basic/util/sb \
	comphelper/util/comphelp \
	configmgr/source/configmgr \
	dbaccess/util/dba \
	drawinglayer/drawinglayer \
	embeddedobj/util/embobj \
	filter/source/config/cache/filterconfig1 \
	filter/source/storagefilterdetect/storagefd \
	filter/source/textfilterdetect/textfd \
	forms/util/frm \
	framework/util/fwk \
	i18npool/util/i18npool \
	linguistic/source/lng \
	oox/util/oox \
	package/source/xstor/xstor \
	package/util/package2 \
	sax/source/expatwrap/expwrap \
	sfx2/util/sfx \
	svl/source/fsstor/fsstorage \
	svtools/util/svt \
	sw/util/msword \
	sw/util/sw \
	sw/util/swd \
	toolkit/util/tk \
	ucb/source/core/ucb1 \
	ucb/source/ucp/file/ucpfile1 \
	unotools/util/utl \
	unoxml/source/rdf/unordf \
	unoxml/source/service/unoxml \
	uui/util/uui \
	$(if $(filter DESKTOP,$(BUILD_TYPE)),xmlhelp/util/ucpchelp1) \
	writerfilter/util/writerfilter \
	xmloff/util/xo \
))
$(eval $(call gb_CppunitTest_use_rdb,sw_globalfilter,services))

$(eval $(call gb_CppunitTest_use_custom_headers,sw_globalfilter,\
	officecfg/registry \
diff --git a/sw/qa/extras/globalfilter/globalfilter.cxx b/sw/qa/extras/globalfilter/globalfilter.cxx
index 9ce7d1ec..5425450 100644
--- a/sw/qa/extras/globalfilter/globalfilter.cxx
+++ b/sw/qa/extras/globalfilter/globalfilter.cxx
@@ -15,6 +15,8 @@
#include <comphelper/processfactory.hxx>
#include <unotxdoc.hxx>
#include <docsh.hxx>
#include <IDocumentRedlineAccess.hxx>
#include <IDocumentContentOperations.hxx>
#include <doc.hxx>
#include <ndgrf.hxx>
#include <drawdoc.hxx>
@@ -37,6 +39,7 @@ public:
#if !defined(_WIN32)
    void testSkipImages();
#endif
    void testRedlineMode();

    CPPUNIT_TEST_SUITE(Test);
    CPPUNIT_TEST(testSwappedOutImageExport);
@@ -50,6 +53,7 @@ public:
#if !defined(_WIN32)
    CPPUNIT_TEST(testSkipImages);
#endif
    CPPUNIT_TEST(testRedlineMode);
    CPPUNIT_TEST_SUITE_END();
};

@@ -817,6 +821,58 @@ void Test::testSkipImages()
}
#endif

void Test::testRedlineMode()
{
    const char* aFilterNames[] = {
        "writer8",
        "Rich Text Format",
        "MS Word 97",
        "Office Open XML Text",
    };

    mxComponent = loadFromDesktop("private:factory/swriter", "com.sun.star.text.TextDocument");
    SwXTextDocument* pTextDoc = dynamic_cast<SwXTextDocument *>(mxComponent.get());
    CPPUNIT_ASSERT(pTextDoc);
    SwDoc* pDoc = pTextDoc->GetDocShell()->GetDoc();

    SwPaM pam(SwPosition(SwNodeIndex(pDoc->GetNodes().GetEndOfContent(), -1)));
    pDoc->getIDocumentContentOperations().InsertString(pam, "foo bar baz");

    IDocumentRedlineAccess & rIDRA(pDoc->getIDocumentRedlineAccess());
    // enable change tracking
    rIDRA.SetRedlineMode(rIDRA.GetRedlineMode()
        | nsRedlineMode_t::REDLINE_ON | nsRedlineMode_t::REDLINE_SHOW_DELETE);

    // need a delete redline to trigger mode switching
    pam.Move(fnMoveForward, fnGoDoc);
    pam.SetMark();
    pam.Move(fnMoveBackward, fnGoDoc);
    pDoc->getIDocumentContentOperations().DeleteAndJoin(pam);

    // hide delete redlines
    RedlineMode_t const nRedlineMode =
        rIDRA.GetRedlineMode() & ~nsRedlineMode_t::REDLINE_SHOW_DELETE;
    rIDRA.SetRedlineMode(nRedlineMode);

    for (size_t nFilter = 0; nFilter < SAL_N_ELEMENTS(aFilterNames); ++nFilter)
    {
        // export the document
        uno::Reference<frame::XStorable> xStorable(mxComponent, uno::UNO_QUERY);

        utl::MediaDescriptor aMediaDescriptor;
        aMediaDescriptor["FilterName"] <<= OUString::createFromAscii(aFilterNames[nFilter]);
        utl::TempFile aTempFile;
        aTempFile.EnableKillingFile();
        xStorable->storeToURL(aTempFile.GetURL(),
                aMediaDescriptor.getAsConstPropertyValueList());

        // tdf#97103 check that redline mode is properly restored
        CPPUNIT_ASSERT_EQUAL_MESSAGE(
            OString(OString("redline mode not restored in ") + aFilterNames[nFilter]).getStr(),
            nRedlineMode, rIDRA.GetRedlineMode());
    }
}

CPPUNIT_TEST_SUITE_REGISTRATION(Test);

CPPUNIT_PLUGIN_IMPLEMENT();
diff --git a/sw/source/filter/basflt/shellio.cxx b/sw/source/filter/basflt/shellio.cxx
index d0a5429..0961d776 100644
--- a/sw/source/filter/basflt/shellio.cxx
+++ b/sw/source/filter/basflt/shellio.cxx
@@ -858,7 +858,6 @@ sal_uLong SwWriter::Write( WriterRef& rxWriter, const OUString* pRealFileName )

    const bool bOrigPurgeOle = pOutDoc->getIDocumentSettingAccess().get(DocumentSettingId::PURGE_OLE);
    pOutDoc->getIDocumentSettingAccess().set(DocumentSettingId::PURGE_OLE, false);
    const RedlineMode_t nOrigRedlineMode = pOutDoc->getIDocumentRedlineAccess().GetRedlineMode();

    sal_uLong nError = 0;
    if( pMedium )
@@ -888,12 +887,10 @@ sal_uLong SwWriter::Write( WriterRef& rxWriter, const OUString* pRealFileName )
            else
                delete pPam;
        }
        pOutDoc->getIDocumentRedlineAccess().SetRedlineMode(nOrigRedlineMode);
    }
    else
    {
        delete pPam;            // delete the created Pam
        pOutDoc->getIDocumentRedlineAccess().SetRedlineMode(nOrigRedlineMode);
        // Everything was written successfully? Tell the document!
        if ( !IsError( nError ) && !pDoc )
        {
diff --git a/sw/source/filter/ww8/wrtww8.cxx b/sw/source/filter/ww8/wrtww8.cxx
index d1c073d..bf92ed1 100644
--- a/sw/source/filter/ww8/wrtww8.cxx
+++ b/sw/source/filter/ww8/wrtww8.cxx
@@ -3134,6 +3134,16 @@ void MSWordExportBase::ExportDocument( bool bWriteAll )
        m_pDoc->getIDocumentDrawModelAccess().GetDrawModel()->GetPage( 0 )->RecalcObjOrdNums();

    ExportDocument_Impl();

    // park m_pCurPam in a "safe place" now that document is fully exported
    // before toggling redline mode to avoid ~SwIndexReg assert e.g. export
    // ooo103014-1.odt to .doc
    // park m_pOrigPam as well, as needed for exporting abi9915-1.odt to doc
    m_pOrigPam->DeleteMark();
    *m_pOrigPam->GetPoint() = SwPosition(m_pDoc->GetNodes().GetEndOfContent());
    *m_pCurPam = *m_pOrigPam;

    m_pDoc->getIDocumentRedlineAccess().SetRedlineMode(m_nOrigRedlineMode);
}

bool SwWW8Writer::InitStd97CodecUpdateMedium( ::msfilter::MSCodec_Std97& rCodec )