fix tdf#121468: preload fixes for Impress filters

was: Re-factor internal filter logic, and impl. preload properly.

Reviewed-on: https://gerrit.libreoffice.org/63761
Tested-by: Jenkins
Reviewed-by: Michael Meeks <michael.meeks@collabora.com>
(cherry picked from commit 7b34fb18a4d60bfc4e32b7c382ac596cbc2e776f)
Reviewed-on: https://gerrit.libreoffice.org/63850

Conflicts:
	sd/inc/sdfilter.hxx
	sd/source/ui/app/sddll.cxx

Change-Id: I4c55ceb19d5db2c1e4756901d0d8b14878641a99
Reviewed-on: https://gerrit.libreoffice.org/64616
Tested-by: Jenkins
Reviewed-by: Samuel Mehrbrodt <Samuel.Mehrbrodt@cib.de>
Reviewed-by: Thorsten Behrens <Thorsten.Behrens@CIB.de>
(cherry picked from commit 9fae95fef82bab8e0760d49ccce51a30ab705941)
Reviewed-on: https://gerrit.libreoffice.org/64726
Reviewed-by: Miklos Vajna <vmiklos@collabora.com>
Tested-by: Christian Lohmaier <lohmaier+LibreOffice@googlemail.com>
diff --git a/sd/inc/sdfilter.hxx b/sd/inc/sdfilter.hxx
index df1421f..7042505 100644
--- a/sd/inc/sdfilter.hxx
+++ b/sd/inc/sdfilter.hxx
@@ -21,6 +21,7 @@
#define INCLUDED_SD_INC_SDFILTER_HXX

#include <sal/types.h>
#include <osl/module.h>
#include <rtl/ustring.hxx>
#include <com/sun/star/frame/XModel.hpp>
#include <com/sun/star/task/XStatusIndicator.hpp>
@@ -44,7 +45,9 @@
    virtual bool            Export() = 0;

#ifndef DISABLE_DYNLOADING
    static ::osl::Module*       OpenLibrary( const OUString& rLibraryName );
    static void Preload();
    /// Open library @rLibraryName and lookup symbol @rFnSymbol
    static oslGenericFunction GetLibrarySymbol( const OUString& rLibraryName, const OUString &rFnSymbol );
#endif

protected:
diff --git a/sd/source/filter/cgm/sdcgmfilter.cxx b/sd/source/filter/cgm/sdcgmfilter.cxx
index 7bd04a2..91a0f62 100644
--- a/sd/source/filter/cgm/sdcgmfilter.cxx
+++ b/sd/source/filter/cgm/sdcgmfilter.cxx
@@ -61,17 +61,14 @@
    class CGMPointer
    {
        ImportCGMPointer m_pPointer;
#ifndef DISABLE_DYNLOADING
        std::unique_ptr<osl::Module> m_xLibrary;
#endif
    public:
        CGMPointer()
        {
#ifdef DISABLE_DYNLOADING
            m_pPointer = ImportCGM;
#else
            m_xLibrary.reset(SdFilter::OpenLibrary("icg"));
            m_pPointer = m_xLibrary ? reinterpret_cast<ImportCGMPointer>(m_xLibrary->getFunctionSymbol("ImportCGM")) : nullptr;
            m_pPointer = reinterpret_cast<ImportCGMPointer>(
                SdFilter::GetLibrarySymbol("icg", "ImportCGM"));
#endif
        }
        ImportCGMPointer get() { return m_pPointer; }
diff --git a/sd/source/filter/sdfilter.cxx b/sd/source/filter/sdfilter.cxx
index b822baa..fbffe2c 100644
--- a/sd/source/filter/sdfilter.cxx
+++ b/sd/source/filter/sdfilter.cxx
@@ -58,14 +58,41 @@
}

#ifndef DISABLE_DYNLOADING

typedef std::map<OUString, std::unique_ptr<osl::Module>> SdModuleMap;
static SdModuleMap g_SdModuleMap;

extern "C" { static void thisModule() {} }

::osl::Module* SdFilter::OpenLibrary( const OUString& rLibraryName )
oslGenericFunction SdFilter::GetLibrarySymbol( const OUString& rLibraryName, const OUString &rFnSymbol )
{
    std::unique_ptr< osl::Module > mod(new osl::Module);
    return mod->loadRelative(&thisModule, ImplGetFullLibraryName(rLibraryName),
                             SAL_LOADMODULE_GLOBAL | SAL_LOADMODULE_LAZY)
        ? mod.release() : nullptr;
    osl::Module *pMod = nullptr;
    auto it = g_SdModuleMap.find(rLibraryName);
    if (it != g_SdModuleMap.end())
        pMod = it->second.get();

    if (!pMod)
    {
        pMod = new osl::Module;
        if (pMod->loadRelative(&thisModule, ImplGetFullLibraryName(rLibraryName),
                               SAL_LOADMODULE_GLOBAL | SAL_LOADMODULE_LAZY))
            g_SdModuleMap[rLibraryName] = std::unique_ptr<osl::Module>(pMod);
        else
        {
            delete pMod;
            pMod = nullptr;
        }
    }
    if (!pMod)
        return nullptr;
    else
        return pMod->getFunctionSymbol(rFnSymbol);
}

void SdFilter::Preload()
{
    (void)GetLibrarySymbol("sdfilt", "ImportPPT");
    (void)GetLibrarySymbol("icg", "ImportCGM");
}

#endif
diff --git a/sd/source/filter/sdpptwrp.cxx b/sd/source/filter/sdpptwrp.cxx
index df3f4da..0eaf993 100644
--- a/sd/source/filter/sdpptwrp.cxx
+++ b/sd/source/filter/sdpptwrp.cxx
@@ -74,7 +74,7 @@

bool SdPPTFilter::Import()
{
    bool    bRet = false;
    bool bRet = false;
    tools::SvRef<SotStorage> pStorage = new SotStorage( mrMedium.GetInStream(), false );
    if( !pStorage->GetError() )
    {
@@ -97,24 +97,18 @@
                mrMedium.SetError(ERRCODE_SVX_READ_FILTER_PPOINT);
            else
            {
#ifndef DISABLE_DYNLOADING
                ::osl::Module* pLibrary = OpenLibrary( mrMedium.GetFilter()->GetUserData() );
                if ( pLibrary )
                {
                    ImportPPTPointer PPTImport = reinterpret_cast< ImportPPTPointer >( pLibrary->getFunctionSymbol( "ImportPPT" ) );
                    if ( PPTImport )
                        bRet = PPTImport( &mrDocument, *pDocStream, *pStorage, mrMedium );

                    if ( !bRet )
                        mrMedium.SetError(SVSTREAM_WRONGVERSION);
                    pLibrary->release(); //TODO: let it get unloaded?
                    delete pLibrary;
                }
#ifdef DISABLE_DYNLOADING
                ImportPPTPointer pPPTImport = ImportPPT;
#else
                bRet = ImportPPT( &mrDocument, *pDocStream, *pStorage, mrMedium );
                ImportPPTPointer pPPTImport = reinterpret_cast< ImportPPTPointer >(
                    SdFilter::GetLibrarySymbol(mrMedium.GetFilter()->GetUserData(), "ImportPPT"));
#endif

                if ( pPPTImport )
                    bRet = pPPTImport( &mrDocument, *pDocStream, *pStorage, mrMedium );

                if ( !bRet )
                    mrMedium.SetError(SVSTREAM_WRONGVERSION);
#endif
            }

            delete pDocStream;
@@ -126,58 +120,50 @@

bool SdPPTFilter::Export()
{
#ifndef DISABLE_DYNLOADING
    ::osl::Module* pLibrary = OpenLibrary( mrMedium.GetFilter()->GetUserData() );
#endif
    bool        bRet = false;
    bool bRet = false;

#ifndef DISABLE_DYNLOADING
    if( pLibrary )
#endif
    if( mxModel.is() )
    {
        if( mxModel.is() )
        {
            tools::SvRef<SotStorage>    xStorRef = new SotStorage( mrMedium.GetOutStream(), false );
#ifndef DISABLE_DYNLOADING
            ExportPPTPointer PPTExport = reinterpret_cast<ExportPPTPointer>(pLibrary->getFunctionSymbol( "ExportPPT" ));
        tools::SvRef<SotStorage> xStorRef = new SotStorage( mrMedium.GetOutStream(), false );

#ifdef DISABLE_DYNLOADING
        ExportPPTPointer PPTExport = ExportPPT;
#else
            ExportPPTPointer PPTExport = ExportPPT;
        ExportPPTPointer PPTExport = reinterpret_cast< ExportPPTPointer >(
            SdFilter::GetLibrarySymbol(mrMedium.GetFilter()->GetUserData(), "ExportPPT"));
#endif

            if( PPTExport && xStorRef.is() )
            {
                sal_uInt32          nCnvrtFlags = 0;
                const SvtFilterOptions& rFilterOptions = SvtFilterOptions::Get();
                if ( rFilterOptions.IsMath2MathType() )
                    nCnvrtFlags |= OLE_STARMATH_2_MATHTYPE;
                if ( rFilterOptions.IsWriter2WinWord() )
                    nCnvrtFlags |= OLE_STARWRITER_2_WINWORD;
                if ( rFilterOptions.IsCalc2Excel() )
                    nCnvrtFlags |= OLE_STARCALC_2_EXCEL;
                if ( rFilterOptions.IsImpress2PowerPoint() )
                    nCnvrtFlags |= OLE_STARIMPRESS_2_POWERPOINT;
                if ( rFilterOptions.IsEnablePPTPreview() )
                    nCnvrtFlags |= 0x8000;
        if( PPTExport && xStorRef.is() )
        {
            sal_uInt32          nCnvrtFlags = 0;
            const SvtFilterOptions& rFilterOptions = SvtFilterOptions::Get();
            if ( rFilterOptions.IsMath2MathType() )
                nCnvrtFlags |= OLE_STARMATH_2_MATHTYPE;
            if ( rFilterOptions.IsWriter2WinWord() )
                nCnvrtFlags |= OLE_STARWRITER_2_WINWORD;
            if ( rFilterOptions.IsCalc2Excel() )
                nCnvrtFlags |= OLE_STARCALC_2_EXCEL;
            if ( rFilterOptions.IsImpress2PowerPoint() )
                nCnvrtFlags |= OLE_STARIMPRESS_2_POWERPOINT;
            if ( rFilterOptions.IsEnablePPTPreview() )
                nCnvrtFlags |= 0x8000;

                mrDocument.SetSwapGraphicsMode( SdrSwapGraphicsMode::TEMP );
            mrDocument.SetSwapGraphicsMode( SdrSwapGraphicsMode::TEMP );

                CreateStatusIndicator();
            CreateStatusIndicator();

                //OUString sBaseURI( "BaseURI");
                std::vector< PropertyValue > aProperties;
                PropertyValue aProperty;
                aProperty.Name = "BaseURI";
                aProperty.Value <<= mrMedium.GetBaseURL( true );
                aProperties.push_back( aProperty );
            //OUString sBaseURI( "BaseURI");
            std::vector< PropertyValue > aProperties;
            PropertyValue aProperty;
            aProperty.Name = "BaseURI";
            aProperty.Value <<= mrMedium.GetBaseURL( true );
            aProperties.push_back( aProperty );

                bRet = PPTExport( aProperties, xStorRef, mxModel, mxStatusIndicator, pBas, nCnvrtFlags );
                xStorRef->Commit();
            }
            bRet = PPTExport( aProperties, xStorRef, mxModel, mxStatusIndicator, pBas, nCnvrtFlags );
            xStorRef->Commit();
        }
#ifndef DISABLE_DYNLOADING
        delete pLibrary;
#endif
    }

    return bRet;
}

@@ -186,20 +172,14 @@
    const SvtFilterOptions& rFilterOptions = SvtFilterOptions::Get();
    if( rFilterOptions.IsLoadPPointBasicStorage() )
    {
#ifndef DISABLE_DYNLOADING
        ::osl::Module* pLibrary = OpenLibrary( mrMedium.GetFilter()->GetUserData() );
        if( pLibrary )
        {
            SaveVBAPointer pSaveVBA= reinterpret_cast<SaveVBAPointer>(pLibrary->getFunctionSymbol( "SaveVBA" ));
            if( pSaveVBA )
            {
                pSaveVBA( static_cast<SfxObjectShell&>(mrDocShell), pBas );
            }
            delete pLibrary;
        }
#ifdef DISABLE_DYNLOADING
        SaveVBAPointer pSaveVBA= SaveVBA;
#else
        SaveVBA( (SfxObjectShell&) mrDocShell, pBas );
        SaveVBAPointer pSaveVBA = reinterpret_cast< SaveVBAPointer >(
            SdFilter::GetLibrarySymbol(mrMedium.GetFilter()->GetUserData(), "SaveVBA"));
#endif
        if( pSaveVBA )
            pSaveVBA( static_cast<SfxObjectShell&>(mrDocShell), pBas );
    }
}

diff --git a/sd/source/ui/app/sddll.cxx b/sd/source/ui/app/sddll.cxx
index 072702d..35b7ca6 100644
--- a/sd/source/ui/app/sddll.cxx
+++ b/sd/source/ui/app/sddll.cxx
@@ -95,6 +95,8 @@
#include <vcl/FilterConfigItem.hxx>
#include <o3tl/make_unique.hxx>
#include <sdabstdlg.hxx>
#include <sdfilter.hxx>
#include <sdmod.hxx>

using namespace ::com::sun::star;

@@ -293,6 +295,7 @@
extern "C" SAL_DLLPUBLIC_EXPORT
void lok_preload_hook()
{
    SdFilter::Preload();
    SdAbstractDialogFactory::Create();
}