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;