tdf#148806 doc vba: highest priority is ThisDocument AutoOpen

Word has three ways of running events at doc open,
although the two AutoOpen methods are exclusive.

One is the special ThisDocument Document_open subroutine.

Another is the AutoOpen subroutine, which is what this
patch is about. It can exist in any module - first come
first served (alphabetically) in doc - except that
ThisDocument is checked first.
[This is very different from Calc - which IGNORES these
functions in ThisWorksheet.]
//TODO: The subroutine must be public

And finally, there can be an AutoOpen module with a Main subroutine.
It is ignored if there is any AutoOpen subroutine.
//TODO: fix the third way.

I tried to create a unit test, but LO's Selection.TypeText
always starts at position 0 for each call, unlike Word
which also starts at position 0 for the first call,
but then remembers where it left off.

Change-Id: I4caf29eefd432c320b5acaf6210222f50a111e89
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/141037
Tested-by: Justin Luth <jluth@mail.com>
Reviewed-by: Justin Luth <jluth@mail.com>
diff --git a/offapi/com/sun/star/script/vba/VBAEventId.idl b/offapi/com/sun/star/script/vba/VBAEventId.idl
index 00989fc..00a524a 100644
--- a/offapi/com/sun/star/script/vba/VBAEventId.idl
+++ b/offapi/com/sun/star/script/vba/VBAEventId.idl
@@ -58,6 +58,11 @@ constants VBAEventId
    const long DOCUMENT_OPEN                        = 1002;
    /** Document about to be closed. No arguments. */
    const long DOCUMENT_CLOSE                       = 1003;
    // auto* subroutines in ThisDocument have highest priority
    const long DOCUMENT_AUTO_NEW = 1004;
    const long DOCUMENT_AUTO_OPEN = 1005;
    const long DOCUMENT_AUTO_CLOSE = 1006;


    // MS Excel (identifiers from 2001 to 2999)

diff --git a/sw/source/ui/vba/vbaeventshelper.cxx b/sw/source/ui/vba/vbaeventshelper.cxx
index ccdb105..d083940 100644
--- a/sw/source/ui/vba/vbaeventshelper.cxx
+++ b/sw/source/ui/vba/vbaeventshelper.cxx
@@ -32,10 +32,13 @@ SwVbaEventsHelper::SwVbaEventsHelper( uno::Sequence< css::uno::Any > const& aArg
{
    using namespace ::com::sun::star::script::ModuleType;
    registerEventHandler( DOCUMENT_NEW,     DOCUMENT,   "Document_New" );
    registerEventHandler(DOCUMENT_AUTO_NEW, DOCUMENT, "AutoNew");
    registerEventHandler( AUTO_NEW,         NORMAL,     "AutoNew" );
    registerEventHandler( DOCUMENT_OPEN,    DOCUMENT,   "Document_Open" );
    registerEventHandler(DOCUMENT_AUTO_OPEN, DOCUMENT, "AutoOpen");
    registerEventHandler( AUTO_OPEN,        NORMAL,     "AutoOpen" );
    registerEventHandler( DOCUMENT_CLOSE,   DOCUMENT,   "Document_Close" );
    registerEventHandler(DOCUMENT_AUTO_CLOSE, DOCUMENT, "AutoClose");
    registerEventHandler( AUTO_CLOSE,       NORMAL,     "AutoClose" );
}

@@ -44,18 +47,22 @@ SwVbaEventsHelper::~SwVbaEventsHelper()
}

bool SwVbaEventsHelper::implPrepareEvent( EventQueue& rEventQueue,
        const EventHandlerInfo& rInfo, const uno::Sequence< uno::Any >& /*rArgs*/ )
        const EventHandlerInfo& rInfo, const uno::Sequence< uno::Any >& rArgs)
{
    switch( rInfo.mnEventId )
    {
        case AUTO_NEW:
            rEventQueue.emplace_back(DOCUMENT_NEW);
        case DOCUMENT_AUTO_NEW:
            // Only one "AutoNew" subroutine can run. ThisDocument is highest priority.
            if (!hasVbaEventHandler(rInfo.mnEventId, rArgs))
                rEventQueue.emplace_back(AUTO_NEW);
        break;
        case AUTO_OPEN:
            rEventQueue.emplace_back(DOCUMENT_OPEN);
        case DOCUMENT_AUTO_OPEN:
            if (!hasVbaEventHandler(rInfo.mnEventId, rArgs))
                rEventQueue.emplace_back(AUTO_OPEN);
        break;
        case AUTO_CLOSE:
            rEventQueue.emplace_back(DOCUMENT_CLOSE);
        case DOCUMENT_AUTO_CLOSE:
            if (!hasVbaEventHandler(rInfo.mnEventId, rArgs))
                rEventQueue.emplace_back(AUTO_CLOSE);
        break;
    }
    return true;
diff --git a/sw/source/uibase/app/docsh2.cxx b/sw/source/uibase/app/docsh2.cxx
index d9e1486..51082a6 100644
--- a/sw/source/uibase/app/docsh2.cxx
+++ b/sw/source/uibase/app/docsh2.cxx
@@ -221,10 +221,12 @@ static void lcl_processCompatibleSfxHint( const uno::Reference< script::vba::XVB
    switch( pSfxEventHint->GetEventId() )
    {
        case SfxEventHintId::CreateDoc:
            xVbaEvents->processVbaEvent(AUTO_NEW, aArgs);
            xVbaEvents->processVbaEvent(DOCUMENT_AUTO_NEW, aArgs);
            xVbaEvents->processVbaEvent(DOCUMENT_NEW, aArgs);
        break;
        case SfxEventHintId::OpenDoc:
            xVbaEvents->processVbaEvent(AUTO_OPEN, aArgs);
            xVbaEvents->processVbaEvent(DOCUMENT_AUTO_OPEN, aArgs);
            xVbaEvents->processVbaEvent(DOCUMENT_OPEN, aArgs);
        break;
        default: break;
    }
@@ -385,7 +387,8 @@ bool SwDocShell::PrepareClose( bool bUI )
        {
            using namespace com::sun::star::script::vba::VBAEventId;
            uno::Sequence< uno::Any > aNoArgs;
            xVbaEvents->processVbaEvent(AUTO_CLOSE, aNoArgs);
            xVbaEvents->processVbaEvent(DOCUMENT_AUTO_CLOSE, aNoArgs);
            xVbaEvents->processVbaEvent(DOCUMENT_CLOSE, aNoArgs);
        }
    }
    return bRet;