[Libreoffice-commits] .: filter/inc filter/source oox/source vbahelper/source

Noel Power noelp at kemper.freedesktop.org
Mon Mar 5 12:21:58 PST 2012


 filter/inc/filter/msfilter/msvbahelper.hxx        |    2 
 filter/source/msfilter/msvbahelper.cxx            |   50 +++++++++++++++++++++-
 oox/source/ole/vbamodule.cxx                      |   36 +++++++++++++++
 vbahelper/source/vbahelper/vbaapplicationbase.cxx |   28 ------------
 4 files changed, 87 insertions(+), 29 deletions(-)

New commits:
commit 14620c3b33cf0315a9b746a0a2418b78d6154821
Author: Noel Power <noel.power at novell.com>
Date:   Mon Mar 5 20:14:13 2012 +0000

    support import of key shortcut for macro ( Excel only )

diff --git a/filter/inc/filter/msfilter/msvbahelper.hxx b/filter/inc/filter/msfilter/msvbahelper.hxx
index 99b20c1..e7e6533 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 fb4fd3d..4c7d3f9 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 d4b041b..9f0e5ff 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 f1ec673..05f2fcf 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


More information about the Libreoffice-commits mailing list