vba: fix registering shortcuts keys defined by the vba macros

On issue with registering was that the registering happened when
the macro source was in	the process to be read into the library,
which is just a	bit too	early, because the macro wasn't	found and
not registered.
Another	issue was with searching for the macro method (hasMacro),
which doesn't search the same when the module name is known and
when it isn't. This was	changed	so we just iterate through the
modules	and call the same "FindMethod" method without any extra
restrictions.

Change-Id: I811cfcaca58e8dfa8bef6cf983a8aff2b60eba35
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/129196
Tested-by: Jenkins
Reviewed-by: Tomaž Vajngerl <quikee@gmail.com>
This commit is contained in:
Tomaž Vajngerl
2022-02-01 02:13:24 +01:00
committed by Tomaž Vajngerl
parent d140817428
commit beb6c62e99
3 changed files with 37 additions and 22 deletions
+7 -10
View File
@@ -173,8 +173,6 @@ static SfxObjectShell* findShellForUrl( const OUString& sMacroURLOrPath )
// if sMod is empty, only standard modules will be searched (no class, document, form modules)
static bool hasMacro( SfxObjectShell const * pShell, const OUString& sLibrary, OUString& sMod, const OUString& sMacro )
{
bool bFound = false;
#if !HAVE_FEATURE_SCRIPTING
(void) pShell;
(void) sLibrary;
@@ -200,18 +198,17 @@ static bool hasMacro( SfxObjectShell const * pShell, const OUString& sLibrary, O
SbModule* pModule = pBasic->FindModule( sMod );
if ( pModule && pModule->FindMethod( sMacro, SbxClassType::Method ))
{
bFound = true;
return true;
}
}
else if( SbMethod* pMethod = dynamic_cast< SbMethod* >( pBasic->Find( sMacro, SbxClassType::Method ) ) )
else
{
if( SbModule* pModule = pMethod->GetModule() )
for (auto const& rModuleRef : pBasic->GetModules())
{
// when searching for a macro without module name, do not search in class/document/form modules
if( pModule->GetModuleType() == script::ModuleType::NORMAL )
if (rModuleRef && rModuleRef->FindMethod(sMacro, SbxClassType::Method))
{
sMod = pModule->GetName();
bFound = true;
sMod = rModuleRef->GetName();
return true;
}
}
}
@@ -219,7 +216,7 @@ static bool hasMacro( SfxObjectShell const * pShell, const OUString& sLibrary, O
}
}
#endif
return bFound;
return false;
}
#endif
+11 -2
View File
@@ -24,6 +24,7 @@
#include <rtl/textenc.h>
#include <rtl/ustring.hxx>
#include <sal/types.h>
#include <vector>
namespace com::sun::star {
namespace container { class XNameAccess; }
@@ -39,6 +40,11 @@ namespace oox {
namespace oox::ole {
struct VbaKeyBinding
{
OUString msApiKey;
OUString msMethodName;
};
class VbaModule
{
@@ -67,15 +73,17 @@ public:
void createAndImportModule(
StorageBase& rVbaStrg,
const css::uno::Reference< css::container::XNameContainer >& rxBasicLib,
const css::uno::Reference< css::container::XNameAccess >& rxDocObjectNA ) const;
const css::uno::Reference< css::container::XNameAccess >& rxDocObjectNA );
/** Creates an empty Basic module in the passed Basic library. */
void createEmptyModule(
const css::uno::Reference< css::container::XNameContainer >& rxBasicLib,
const css::uno::Reference< css::container::XNameAccess >& rxDocObjectNA ) const;
void registerShortcutKeys();
private:
/** Reads and returns the VBA source code from the passed storage. */
OUString readSourceCode( StorageBase& rVbaStrg ) const;
OUString readSourceCode( StorageBase& rVbaStrg );
/** Creates a new Basic module and inserts it into the passed Basic library. */
void createModule(
@@ -97,6 +105,7 @@ private:
bool mbReadOnly;
bool mbPrivate;
bool mbExecutable;
std::vector<VbaKeyBinding> maKeyBindings;
};
+19 -10
View File
@@ -127,10 +127,26 @@ void VbaModule::importDirRecords( BinaryInputStream& rDirStrm )
void VbaModule::createAndImportModule( StorageBase& rVbaStrg,
const Reference< container::XNameContainer >& rxBasicLib,
const Reference< container::XNameAccess >& rxDocObjectNA ) const
const Reference< container::XNameAccess >& rxDocObjectNA )
{
OUString aVBASourceCode = readSourceCode( rVbaStrg );
createModule( aVBASourceCode, rxBasicLib, rxDocObjectNA );
registerShortcutKeys();
}
void VbaModule::registerShortcutKeys()
{
for (VbaKeyBinding const& rKeyBinding : maKeyBindings)
{
try
{
KeyEvent aKeyEvent = ooo::vba::parseKeyEvent(rKeyBinding.msApiKey);
ooo::vba::applyShortCutKeyBinding(mxDocModel, aKeyEvent, rKeyBinding.msMethodName);
}
catch (const Exception&)
{
}
}
}
void VbaModule::createEmptyModule( const Reference< container::XNameContainer >& rxBasicLib,
@@ -139,7 +155,7 @@ void VbaModule::createEmptyModule( const Reference< container::XNameContainer >&
createModule( u"", rxBasicLib, rxDocObjectNA );
}
OUString VbaModule::readSourceCode( StorageBase& rVbaStrg ) const
OUString VbaModule::readSourceCode( StorageBase& rVbaStrg )
{
OUStringBuffer aSourceCode(512);
static const char sUnmatchedRemovedTag[] = "Rem removed unmatched Sub/End: ";
@@ -189,14 +205,7 @@ OUString VbaModule::readSourceCode( StorageBase& rVbaStrg ) const
// cntrl modifier is explicit ( but could be cntrl+shift ), parseKeyEvent
// will handle and uppercase letter appropriately
OUString sApiKey = "^" + sKey;
try
{
KeyEvent aKeyEvent = ooo::vba::parseKeyEvent( sApiKey );
ooo::vba::applyShortCutKeyBinding( mxDocModel, aKeyEvent, sProc );
}
catch (const Exception&)
{
}
maKeyBindings.push_back({sApiKey, sProc});
}
}
}