summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--filter/inc/filter/msfilter/msvbahelper.hxx2
-rw-r--r--filter/source/msfilter/msvbahelper.cxx50
-rw-r--r--oox/source/ole/vbamodule.cxx36
-rw-r--r--vbahelper/source/vbahelper/vbaapplicationbase.cxx28
4 files changed, 87 insertions, 29 deletions
diff --git a/filter/inc/filter/msfilter/msvbahelper.hxx b/filter/inc/filter/msfilter/msvbahelper.hxx
index 99b20c152400..e7e653347626 100644
--- a/filter/inc/filter/msfilter/msvbahelper.hxx
+++ b/filter/inc/filter/msfilter/msvbahelper.hxx
@@ -34,6 +34,7 @@
#include <com/sun/star/lang/XServiceInfo.hpp>
#include <com/sun/star/script/vba/XVBAMacroResolver.hpp>
#include <com/sun/star/awt/KeyEvent.hpp>
+#include <com/sun/star/frame/XModel.hpp>
#include "filter/msfilter/msfilterdllapi.h"
namespace ooo {
namespace vba {
@@ -56,6 +57,7 @@ MSFILTER_DLLPUBLIC ::rtl::OUString resolveVBAMacro( SfxObjectShell* pShell, cons
MSFILTER_DLLPUBLIC MacroResolvedInfo resolveVBAMacro( SfxObjectShell* pShell, const ::rtl::OUString& rMacroName, bool bSearchGlobalTemplates = false );
MSFILTER_DLLPUBLIC sal_Bool executeMacro( SfxObjectShell* pShell, const String& sMacroName, com::sun::star::uno::Sequence< com::sun::star::uno::Any >& aArgs, com::sun::star::uno::Any& aRet, const com::sun::star::uno::Any& aCaller );
MSFILTER_DLLPUBLIC ::com::sun::star::awt::KeyEvent parseKeyEvent( const ::rtl::OUString& sKey ) throw (::com::sun::star::uno::RuntimeException);
+MSFILTER_DLLPUBLIC void applyShortCutKeyBinding ( const ::com::sun::star::uno::Reference< com::sun::star::frame::XModel >& rxDoc, const ::com::sun::star::awt::KeyEvent& rKeyEvent, const ::rtl::OUString& sMacro ) throw (::com::sun::star::uno::RuntimeException);
// ============================================================================
typedef ::cppu::WeakImplHelper3<
diff --git a/filter/source/msfilter/msvbahelper.cxx b/filter/source/msfilter/msvbahelper.cxx
index fb4fd3d40939..4c7d3f9804e7 100644
--- a/filter/source/msfilter/msvbahelper.cxx
+++ b/filter/source/msfilter/msvbahelper.cxx
@@ -44,6 +44,8 @@
#include <com/sun/star/awt/KeyModifier.hpp>
#include <svtools/acceleratorexecute.hxx>
+#include <com/sun/star/ui/XUIConfigurationManagerSupplier.hpp>
+#include <com/sun/star/ui/XUIConfigurationManager.hpp>
#include <map>
using namespace ::com::sun::star;
@@ -584,6 +586,7 @@ void SAL_CALL VBAMacroResolver::initialize( const uno::Sequence< uno::Any >& rAr
OSL_ENSURE( false, "VBAMacroResolver::resolveScriptURLtoVBAMacro - not implemented" );
throw uno::RuntimeException();
}
+
bool getModifier( char c, sal_uInt16& mod )
{
static const char modifiers[] = "+^%";
@@ -607,11 +610,17 @@ sal_uInt16 parseChar( char c ) throw ( uno::RuntimeException )
sal_uInt16 nVclKey = 0;
// do we care about locale here for isupper etc. ? probably not
if ( isalpha( c ) )
+ {
nVclKey |= ( toupper( c ) - 'A' ) + KEY_A;
+ if ( isupper( c ) )
+ nVclKey |= KEY_SHIFT;
+ }
else if ( isdigit( c ) )
nVclKey |= ( c - '0' ) + KEY_0;
else if ( c == '~' ) // special case
nVclKey = KEY_RETURN;
+ else if ( c == ' ' ) // special case
+ nVclKey = KEY_SPACE;
else // I guess we have a problem ( but not sure if locale specific keys might come into play here )
throw uno::RuntimeException();
return nVclKey;
@@ -640,6 +649,9 @@ KeyCodeEntry aMSKeyCodesData[] = {
{ "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 },
@@ -675,7 +687,7 @@ awt::KeyEvent parseKeyEvent( const ::rtl::OUString& Key ) throw ( uno::RuntimeEx
{
if ( ! getModifier( Key[ i ], nVclKey ) )
{
- sKeyCode = Key.copy( i ).trim();
+ sKeyCode = Key.copy( i );
break;
}
}
@@ -709,6 +721,42 @@ awt::KeyEvent parseKeyEvent( const ::rtl::OUString& Key ) throw ( uno::RuntimeEx
return aKeyEvent;
}
+void applyShortCutKeyBinding ( const uno::Reference< frame::XModel >& rxModel, const awt::KeyEvent& rKeyEvent, const ::rtl::OUString& rMacroName ) throw (uno::RuntimeException)
+{
+ rtl::OUString MacroName( rMacroName );
+ if ( !MacroName.isEmpty() )
+ {
+ ::rtl::OUString sSeparator(RTL_CONSTASCII_USTRINGPARAM("/"));
+ ::rtl::OUString sMacroSeparator(RTL_CONSTASCII_USTRINGPARAM("!"));
+ ::rtl::OUString aMacroName = MacroName.trim();
+ if (0 == aMacroName.indexOf('!'))
+ MacroName = aMacroName.copy(1).trim();
+ SfxObjectShell* pShell = NULL;
+ if ( rxModel.is() )
+ {
+ uno::Reference< lang::XUnoTunnel > xObjShellTunnel( rxModel, uno::UNO_QUERY_THROW );
+ pShell = reinterpret_cast<SfxObjectShell*>( xObjShellTunnel->getSomething(SfxObjectShell::getUnoTunnelId()));
+ if ( !pShell )
+ throw uno::RuntimeException();
+ }
+ MacroResolvedInfo aMacroInfo = resolveVBAMacro( pShell, aMacroName );
+ if( !aMacroInfo.mbFound )
+ throw uno::RuntimeException( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("The procedure doesn't exist") ), uno::Reference< uno::XInterface >() );
+ MacroName = aMacroInfo.msResolvedMacro;
+ }
+ uno::Reference< ui::XUIConfigurationManagerSupplier > xCfgSupplier(rxModel, uno::UNO_QUERY_THROW);
+ uno::Reference< ui::XUIConfigurationManager > xCfgMgr = xCfgSupplier->getUIConfigurationManager();
+
+ uno::Reference< ui::XAcceleratorConfiguration > xAcc( xCfgMgr->getShortCutManager(), uno::UNO_QUERY_THROW );
+ if ( MacroName.isEmpty() )
+ // I believe this should really restore the [application] default. Since
+ // afaik we don't actually setup application default bindings on import
+ // we don't even know what the 'default' would be for this key
+ xAcc->removeKeyEvent( rKeyEvent );
+ else
+ xAcc->setKeyEvent( rKeyEvent, ooo::vba::makeMacroURL( MacroName ) );
+
+}
// ============================================================================
} // namespace vba
diff --git a/oox/source/ole/vbamodule.cxx b/oox/source/ole/vbamodule.cxx
index d4b041b2e1bf..9f0e5ffe6bf8 100644
--- a/oox/source/ole/vbamodule.cxx
+++ b/oox/source/ole/vbamodule.cxx
@@ -33,7 +33,9 @@
#include <com/sun/star/script/ModuleInfo.hpp>
#include <com/sun/star/script/ModuleType.hpp>
#include <com/sun/star/script/vba/XVBAModuleInfo.hpp>
+#include <com/sun/star/awt/KeyEvent.hpp>
#include <cppuhelper/implbase1.hxx>
+#include <filter/msfilter/msvbahelper.hxx>
#include "oox/helper/binaryinputstream.hxx"
#include "oox/helper/storagebase.hxx"
#include "oox/helper/textinputstream.hxx"
@@ -54,6 +56,7 @@ using namespace ::com::sun::star::uno;
using ::rtl::OUString;
using ::rtl::OUStringBuffer;
+using ::com::sun::star::awt::KeyEvent;
// ============================================================================
typedef ::cppu::WeakImplHelper1< XIndexContainer > OleIdToNameContainer_BASE;
typedef boost::unordered_map< sal_Int32, rtl::OUString > ObjIdToName;
@@ -249,7 +252,38 @@ OUString VbaModule::readSourceCode( StorageBase& rVbaStrg, const Reference< XNam
if( aCodeLine.matchAsciiL( RTL_CONSTASCII_STRINGPARAM( "Attribute " ) ) )
{
// attribute
- extractOleOverrideFromAttr( aCodeLine, rxOleNameOverrides );
+ int index = aCodeLine.indexOf( ".VB_ProcData.VB_Invoke_Func = " );
+ if ( index != -1 )
+ {
+ // format is
+ // 'Attribute Procedure.VB_ProcData.VB_Invoke_Func = "*\n14"'
+ // where 'Procedure' is the procedure name and '*' is the shortcut key
+ // note: his is only relevant for Excel, seems that
+ // word doesn't store the shortcut in the module
+ // attributes
+ int nSpaceIndex = aCodeLine.indexOf(' ');
+ rtl::OUString sProc = aCodeLine.copy( nSpaceIndex + 1, index - nSpaceIndex - 1);
+ // for Excel short cut key seems limited to cntrl+'a-z, A-Z'
+ rtl::OUString sKey = aCodeLine.copy( aCodeLine.lastIndexOf("= ") + 3, 1 );
+ // only alpha key valid for key shortcut, however the api will accept other keys
+ if ( !isalpha( (char)sKey[ 0 ] ) )
+ {
+ // cntrl modifier is explicit ( but could be cntrl+shift ), parseKeyEvent
+ // will handle and uppercase letter appropriately
+ rtl::OUString sApiKey = "^";
+ sApiKey += sKey;
+ try
+ {
+ KeyEvent aKeyEvent = ooo::vba::parseKeyEvent( sApiKey );
+ ooo::vba::applyShortCutKeyBinding( mxDocModel, aKeyEvent, sProc );
+ }
+ catch( Exception& )
+ {
+ }
+ }
+ }
+ else
+ extractOleOverrideFromAttr( aCodeLine, rxOleNameOverrides );
}
else
{
diff --git a/vbahelper/source/vbahelper/vbaapplicationbase.cxx b/vbahelper/source/vbahelper/vbaapplicationbase.cxx
index f1ec673e8270..05f2fcf4ddca 100644
--- a/vbahelper/source/vbahelper/vbaapplicationbase.cxx
+++ b/vbahelper/source/vbahelper/vbaapplicationbase.cxx
@@ -42,10 +42,7 @@
#include <com/sun/star/document/XDocumentPropertiesSupplier.hpp>
#include <com/sun/star/document/XEmbeddedScripts.hpp>
#include <com/sun/star/awt/XWindow2.hpp>
-#include <com/sun/star/ui/XUIConfigurationManagerSupplier.hpp>
-#include <com/sun/star/ui/XUIConfigurationManager.hpp>
-#include <svtools/acceleratorexecute.hxx>
#include <boost/unordered_map.hpp>
#include <filter/msfilter/msvbahelper.hxx>
#include <tools/datetime.hxx>
@@ -300,30 +297,7 @@ VbaApplicationBase::OnKey( const ::rtl::OUString& Key, const uno::Any& Procedure
if ( !xModel.is() )
xModel = getCurrentDocument();
- if ( !MacroName.isEmpty() )
- {
- ::rtl::OUString sSeparator(RTL_CONSTASCII_USTRINGPARAM("/"));
- ::rtl::OUString sMacroSeparator(RTL_CONSTASCII_USTRINGPARAM("!"));
- ::rtl::OUString aMacroName = MacroName.trim();
- if (0 == aMacroName.indexOf('!'))
- MacroName = aMacroName.copy(1).trim();
-
- MacroResolvedInfo aMacroInfo = resolveVBAMacro( getSfxObjShell( xModel ), aMacroName );
- if( !aMacroInfo.mbFound )
- throw uno::RuntimeException( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("The procedure doesn't exist") ), uno::Reference< uno::XInterface >() );
- MacroName = aMacroInfo.msResolvedMacro;
- }
- uno::Reference< ui::XUIConfigurationManagerSupplier > xCfgSupplier(xModel, uno::UNO_QUERY_THROW);
- uno::Reference< ui::XUIConfigurationManager > xCfgMgr = xCfgSupplier->getUIConfigurationManager();
-
- uno::Reference< ui::XAcceleratorConfiguration > xAcc( xCfgMgr->getShortCutManager(), uno::UNO_QUERY_THROW );
- if ( MacroName.isEmpty() )
- // I believe this should really restore the [application] default. Since
- // afaik we don't actually setup application default bindings on import
- // we don't even know what the 'default' would be for this key
- xAcc->removeKeyEvent( aKeyEvent );
- else
- xAcc->setKeyEvent( aKeyEvent, ooo::vba::makeMacroURL( MacroName ) );
+ applyShortCutKeyBinding( xModel, aKeyEvent, MacroName );
}
uno::Any SAL_CALL