diff options
Diffstat (limited to 'filter/source/msfilter/msvbahelper.cxx')
-rw-r--r-- | filter/source/msfilter/msvbahelper.cxx | 254 |
1 files changed, 131 insertions, 123 deletions
diff --git a/filter/source/msfilter/msvbahelper.cxx b/filter/source/msfilter/msvbahelper.cxx index ee40bede6bd4..17282aebf61a 100644 --- a/filter/source/msfilter/msvbahelper.cxx +++ b/filter/source/msfilter/msvbahelper.cxx @@ -38,41 +38,43 @@ #include <unotools/pathoptions.hxx> #include <rtl/character.hxx> #include <sfx2/objsh.hxx> - +#include <o3tl/string_view.hxx> #include <svtools/acceleratorexecute.hxx> #include <com/sun/star/ui/XUIConfigurationManagerSupplier.hpp> #include <com/sun/star/ui/XUIConfigurationManager.hpp> -#include <map> +#include <frozen/bits/defines.h> +#include <frozen/bits/elsa_std.h> +#include <frozen/unordered_map.h> using namespace ::com::sun::star; namespace ooo::vba { -constexpr OUStringLiteral sUrlPart0( u"vnd.sun.star.script:" ); -constexpr OUStringLiteral sUrlPart1( u"?language=Basic&location=document" ); +constexpr OUString sUrlPart0( u"vnd.sun.star.script:"_ustr ); +constexpr OUString sUrlPart1( u"?language=Basic&location=document"_ustr ); OUString makeMacroURL( std::u16string_view sMacroName ) { return sUrlPart0 + sMacroName + sUrlPart1; } -OUString extractMacroName( const OUString& rMacroUrl ) +OUString extractMacroName( std::u16string_view rMacroUrl ) { - if( rMacroUrl.startsWith( sUrlPart0 ) && rMacroUrl.endsWith( sUrlPart1 ) ) + if( o3tl::starts_with(rMacroUrl, sUrlPart0 ) && o3tl::ends_with(rMacroUrl, sUrlPart1 ) ) { - return rMacroUrl.copy( sUrlPart0.getLength(), - rMacroUrl.getLength() - sUrlPart0.getLength() - sUrlPart1.getLength() ); + return OUString(rMacroUrl.substr( sUrlPart0.getLength(), + rMacroUrl.size() - sUrlPart0.getLength() - sUrlPart1.getLength() )); } return OUString(); } -static OUString trimMacroName( const OUString& rMacroName ) +static std::u16string_view trimMacroName( std::u16string_view rMacroName ) { // the name may contain whitespaces and may be enclosed in apostrophs - OUString aMacroName = rMacroName.trim(); - sal_Int32 nMacroLen = aMacroName.getLength(); + std::u16string_view aMacroName = o3tl::trim(rMacroName); + size_t nMacroLen = aMacroName.size(); if( (nMacroLen >= 2) && (aMacroName[ 0 ] == '\'') && (aMacroName[ nMacroLen - 1 ] == '\'') ) - aMacroName = aMacroName.copy( 1, nMacroLen - 2 ).trim(); + aMacroName = o3tl::trim(aMacroName.substr( 1, nMacroLen - 2 )); return aMacroName; } @@ -112,7 +114,7 @@ static SfxObjectShell* findShellForUrl( const OUString& sMacroURLOrPath ) uno::Reference< frame::XFrame > xFrame( xModel->getCurrentController()->getFrame(), uno::UNO_SET_THROW ); uno::Reference< beans::XPropertySet > xProps( xFrame, uno::UNO_QUERY_THROW ); xProps->getPropertyValue("Title") >>= aName; - aName = aName.getToken(0, '-').trim(); + aName = o3tl::trim(o3tl::getToken(aName, 0, '-')); if( sMacroURLOrPath.lastIndexOf( aName ) >= 0 ) { pFoundShell = pShell; @@ -171,55 +173,70 @@ static SfxObjectShell* findShellForUrl( const OUString& sMacroURLOrPath ) // sMod can be empty ( but we really need the library to search in ) // if sMod is empty and a macro is found then sMod is updated // 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 ) +static bool hasMacro(SfxObjectShell const* pShell, const OUString& sLibrary, OUString& sMod, + const OUString& sMacro, bool bOnlyPublic, const OUString& sSkipModule) { - bool bFound = false; - #if !HAVE_FEATURE_SCRIPTING (void) pShell; (void) sLibrary; (void) sMod; (void) sMacro; + (void) bOnlyPublic; + (void) sSkipModule; #else - if ( !sLibrary.isEmpty() && !sMacro.isEmpty() ) + if (sLibrary.isEmpty() || sMacro.isEmpty()) + return false; + + BasicManager* pBasicMgr = pShell->GetBasicManager(); + if (!pBasicMgr) + return false; + + StarBASIC* pBasic = pBasicMgr->GetLib(sLibrary); + if (!pBasic) { - BasicManager* pBasicMgr = pShell-> GetBasicManager(); - if ( pBasicMgr ) + sal_uInt16 nId = pBasicMgr->GetLibId(sLibrary); + pBasicMgr->LoadLib(nId); + pBasic = pBasicMgr->GetLib(sLibrary); + } + if (!pBasic) + return false; + + if (!sMod.isEmpty()) // we wish to find the macro is a specific module + { + SbModule* pModule = pBasic->FindModule(sMod); + if (!pModule) + return false; + SbMethod* pMeth = pModule->FindMethod(sMacro, SbxClassType::Method); + + // Must be compiled before we can trust SbxFlagBits::Private + if (pMeth && bOnlyPublic && !pModule->IsCompiled()) + pModule->Compile(); + + return pMeth && (!bOnlyPublic || !pMeth->IsSet(SbxFlagBits::Private)); + } + + for (auto const& rModuleRef : pBasic->GetModules()) + { + SbMethod* pMeth = rModuleRef->FindMethod(sMacro, SbxClassType::Method); + if (pMeth) { - StarBASIC* pBasic = pBasicMgr->GetLib( sLibrary ); - if ( !pBasic ) - { - sal_uInt16 nId = pBasicMgr->GetLibId( sLibrary ); - pBasicMgr->LoadLib( nId ); - pBasic = pBasicMgr->GetLib( sLibrary ); - } - if ( pBasic ) + if (rModuleRef->GetName() == sSkipModule) + continue; + + if (bOnlyPublic) { - if ( !sMod.isEmpty() ) // we wish to find the macro is a specific module - { - SbModule* pModule = pBasic->FindModule( sMod ); - if ( pModule && pModule->FindMethod( sMacro, SbxClassType::Method )) - { - bFound = true; - } - } - else if( SbMethod* pMethod = dynamic_cast< SbMethod* >( pBasic->Find( sMacro, SbxClassType::Method ) ) ) - { - if( SbModule* pModule = pMethod->GetModule() ) - { - // when searching for a macro without module name, do not search in class/document/form modules - if( pModule->GetModuleType() == script::ModuleType::NORMAL ) - { - sMod = pModule->GetName(); - bFound = true; - } - } - } + if (!rModuleRef->IsCompiled()) + rModuleRef->Compile(); + + if (pMeth->IsSet(SbxFlagBits::Private)) + continue; } + sMod = rModuleRef->GetName(); + return true; } } #endif - return bFound; + return false; } #endif @@ -246,7 +263,7 @@ static void parseMacro( const OUString& sMacro, OUString& sContainer, OUString& { sProcedure = sMacro.copy( nMacroDot + 1 ); - sal_Int32 nContainerDot = sMacro.lastIndexOf( '.', nMacroDot - 1 ); + const sal_Int32 nContainerDot = sMacro.lastIndexOf('.', nMacroDot); if ( nContainerDot != -1 ) { sModule = sMacro.copy( nContainerDot + 1, nMacroDot - nContainerDot - 1 ); @@ -261,19 +278,23 @@ static void parseMacro( const OUString& sMacro, OUString& sContainer, OUString& #endif -OUString resolveVBAMacro( SfxObjectShell const * pShell, const OUString& rLibName, const OUString& rModuleName, const OUString& rMacroName ) +OUString resolveVBAMacro(SfxObjectShell const* pShell, const OUString& rLibName, + const OUString& rModuleName, const OUString& rMacroName, + bool bOnlyPublic, const OUString& sSkipModule) { #if !HAVE_FEATURE_SCRIPTING (void) pShell; (void) rLibName; (void) rModuleName; (void) rMacroName; + (void) bOnlyPublic; + (void) sSkipModule; #else if( pShell ) { OUString aLibName = rLibName.isEmpty() ? getDefaultProjectName( pShell ) : rLibName ; OUString aModuleName = rModuleName; - if( hasMacro( pShell, aLibName, aModuleName, rMacroName ) ) + if (hasMacro(pShell, aLibName, aModuleName, rMacroName, bOnlyPublic, sSkipModule)) return aLibName + "." + aModuleName + "." + rMacroName; } #endif @@ -293,34 +314,34 @@ MacroResolvedInfo resolveVBAMacro( SfxObjectShell* pShell, const OUString& Macro return MacroResolvedInfo(); // the name may be enclosed in apostrophs - OUString aMacroName = trimMacroName( MacroName ); + std::u16string_view aMacroName = trimMacroName( MacroName ); // parse the macro name - sal_Int32 nDocSepIndex = aMacroName.indexOf( '!' ); - if( nDocSepIndex > 0 ) + size_t nDocSepIndex = aMacroName.find( '!' ); + if( nDocSepIndex > 0 && nDocSepIndex != std::u16string_view::npos ) { // macro specified by document name // find document shell for document name and call ourselves // recursively // assume for now that the document name is *this* document - OUString sDocUrlOrPath = aMacroName.copy( 0, nDocSepIndex ); - aMacroName = aMacroName.copy( nDocSepIndex + 1 ); + std::u16string_view sDocUrlOrPath = aMacroName.substr( 0, nDocSepIndex ); + aMacroName = aMacroName.substr( nDocSepIndex + 1 ); SAL_INFO("filter.ms", "doc search, current shell is " << pShell); SfxObjectShell* pFoundShell = nullptr; if( bSearchGlobalTemplates ) { SvtPathOptions aPathOpt; const OUString& aAddinPath = aPathOpt.GetAddinPath(); - if( sDocUrlOrPath.startsWith( aAddinPath ) ) + if( o3tl::starts_with(sDocUrlOrPath, aAddinPath) ) pFoundShell = pShell; } if( !pFoundShell ) - pFoundShell = findShellForUrl( sDocUrlOrPath ); + pFoundShell = findShellForUrl( OUString(sDocUrlOrPath) ); SAL_INFO( "filter.ms", "doc search, after find, found shell is " << pFoundShell); - return resolveVBAMacro( pFoundShell, aMacroName ); + return resolveVBAMacro( pFoundShell, OUString(aMacroName) ); } // macro is contained in 'this' document ( or code imported from a template @@ -331,7 +352,7 @@ MacroResolvedInfo resolveVBAMacro( SfxObjectShell* pShell, const OUString& Macro // macro format = Container.Module.Procedure OUString sContainer, sModule, sProcedure; - parseMacro( aMacroName, sContainer, sModule, sProcedure ); + parseMacro( OUString(aMacroName), sContainer, sModule, sProcedure ); #if 0 // As long as service VBAProjectNameProvider isn't supported in the model, disable the createInstance call @@ -444,7 +465,7 @@ MacroResolvedInfo resolveVBAMacro( SfxObjectShell* pShell, const OUString& Macro for (auto const& search : sSearchList) { - aRes.mbFound = hasMacro( pShell, search, sModule, sProcedure ); + aRes.mbFound = hasMacro(pShell, search, sModule, sProcedure, /*bOnlyPublic=*/false, ""); if ( aRes.mbFound ) { sContainer = search; @@ -556,7 +577,7 @@ OUString SAL_CALL VBAMacroResolver::resolveVBAMacroToScriptURL( const OUString& throw uno::RuntimeException(); // the name may be enclosed in apostrophs - OUString aMacroName = trimMacroName( rVBAMacroName ); + OUString aMacroName( trimMacroName( rVBAMacroName ) ); if( aMacroName.isEmpty() ) throw lang::IllegalArgumentException(); @@ -624,95 +645,82 @@ static sal_uInt16 parseChar( sal_Unicode c ) return nVclKey; } -namespace { +namespace +{ -struct KeyCodeEntry +constexpr frozen::unordered_map<std::u16string_view, sal_uInt16, 34> s_KeyCodes { - const char* sName; - sal_uInt16 nCode; + { u"BACKSPACE", KEY_BACKSPACE }, + { u"BS", KEY_BACKSPACE }, + { u"DELETE", KEY_DELETE }, + { u"DEL", KEY_DELETE }, + { u"DOWN", KEY_DOWN }, + { u"UP", KEY_UP }, + { u"LEFT", KEY_LEFT }, + { u"RIGHT", KEY_RIGHT }, + { u"END", KEY_END }, + { u"ESCAPE", KEY_ESCAPE }, + { u"ESC", KEY_ESCAPE }, + { u"HELP", KEY_HELP }, + { u"HOME", KEY_HOME }, + { u"PGDN", KEY_PAGEDOWN }, + { u"PGUP", KEY_PAGEUP }, + { u"INSERT", KEY_INSERT }, + { u"SCROLLLOCK", KEY_SCROLLLOCK }, + { u"NUMLOCK", KEY_NUMLOCK }, + { u"TAB", KEY_TAB }, + { u"F1", KEY_F1 }, + { u"F2", KEY_F2 }, + { u"F3", KEY_F3 }, + { u"F4", KEY_F4 }, + { u"F5", KEY_F5 }, + { u"F6", KEY_F6 }, + { u"F7", KEY_F7 }, + { u"F8", KEY_F8 }, + { u"F9", KEY_F9 }, + { u"F10", KEY_F10 }, + { u"F11", KEY_F11 }, + { u"F12", KEY_F12 }, + { u"F13", KEY_F13 }, + { u"F14", KEY_F14 }, + { u"F15", KEY_F15 } }; -} - -KeyCodeEntry const aMSKeyCodesData[] = { - { "BACKSPACE", KEY_BACKSPACE }, - { "BS", KEY_BACKSPACE }, - { "DELETE", KEY_DELETE }, - { "DEL", KEY_DELETE }, - { "DOWN", KEY_DOWN }, - { "UP", KEY_UP }, - { "LEFT", KEY_LEFT }, - { "RIGHT", KEY_RIGHT }, - { "END", KEY_END }, - { "ESCAPE", KEY_ESCAPE }, - { "ESC", KEY_ESCAPE }, - { "HELP", KEY_HELP }, - { "HOME", KEY_HOME }, - { "PGDN", KEY_PAGEDOWN }, - { "PGUP", KEY_PAGEUP }, - { "INSERT", KEY_INSERT }, - { "SCROLLLOCK", KEY_SCROLLLOCK }, - { "NUMLOCK", KEY_NUMLOCK }, - { "TAB", KEY_TAB }, - { "F1", KEY_F1 }, - { "F2", KEY_F2 }, - { "F3", KEY_F3 }, - { "F4", KEY_F4 }, - { "F5", KEY_F5 }, - { "F6", KEY_F6 }, - { "F7", KEY_F7 }, - { "F8", KEY_F8 }, - { "F9", KEY_F9 }, - { "F10", KEY_F10 }, - { "F11", KEY_F11 }, - { "F12", KEY_F12 }, - { "F13", KEY_F13 }, - { "F14", KEY_F14 }, - { "F15", KEY_F15 }, -}; +} // end anonymous namespace -awt::KeyEvent parseKeyEvent( const OUString& Key ) +awt::KeyEvent parseKeyEvent( std::u16string_view Key ) { - static std::map< OUString, sal_uInt16 > s_KeyCodes = []() - { - std::map< OUString, sal_uInt16 > tmp; - for (KeyCodeEntry const & i : aMSKeyCodesData) - { - tmp[ OUString::createFromAscii( i.sName ) ] = i.nCode; - } - return tmp; - }(); - OUString sKeyCode; + std::u16string_view sKeyCode; sal_uInt16 nVclKey = 0; // parse the modifier if any - for ( int i=0; i<Key.getLength(); ++i ) + for ( size_t i=0; i<Key.size(); ++i ) { if ( ! getModifier( Key[ i ], nVclKey ) ) { - sKeyCode = Key.copy( i ); + sKeyCode = Key.substr( i ); break; } } // check if keycode is surrounded by '{}', if so scoop out the contents // else it should be just one char of ( 'a-z,A-Z,0-9' ) - if ( sKeyCode.getLength() == 1 ) // ( a single char ) + if ( sKeyCode.size() == 1 ) // ( a single char ) { nVclKey |= parseChar( sKeyCode[ 0 ] ); } else // key should be enclosed in '{}' { - if ( sKeyCode.getLength() < 3 || sKeyCode[0] != '{' || sKeyCode[sKeyCode.getLength() - 1 ] != '}' ) + if ( sKeyCode.size() < 3 || sKeyCode[0] != '{' || sKeyCode[sKeyCode.size() - 1 ] != '}' ) throw uno::RuntimeException(); - sKeyCode = sKeyCode.copy(1, sKeyCode.getLength() - 2 ); + sKeyCode = sKeyCode.substr(1, sKeyCode.size() - 2 ); - if ( sKeyCode.getLength() == 1 ) + if ( sKeyCode.size() == 1 ) nVclKey |= parseChar( sKeyCode[ 0 ] ); else { - auto it = s_KeyCodes.find( sKeyCode ); + auto it = s_KeyCodes.find(sKeyCode); if ( it == s_KeyCodes.end() ) // unknown or unsupported throw uno::RuntimeException(); nVclKey |= it->second; @@ -730,7 +738,7 @@ void applyShortCutKeyBinding ( const uno::Reference< frame::XModel >& rxModel, c { OUString aMacroName = MacroName.trim(); if( aMacroName.startsWith("!") ) - aMacroName = aMacroName.copy(1).trim(); + aMacroName = o3tl::trim(aMacroName.subView(1)); SfxObjectShell* pShell = nullptr; if ( rxModel.is() ) { |