LCOV - code coverage report
Current view: top level - filter/source/msfilter - msvbahelper.cxx (source / functions) Hit Total Coverage
Test: commit e02a6cb2c3e2b23b203b422e4e0680877f232636 Lines: 0 290 0.0 %
Date: 2014-04-14 Functions: 0 28 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2             : /*
       3             :  * This file is part of the LibreOffice project.
       4             :  *
       5             :  * This Source Code Form is subject to the terms of the Mozilla Public
       6             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       7             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
       8             :  *
       9             :  * This file incorporates work covered by the following license notice:
      10             :  *
      11             :  *   Licensed to the Apache Software Foundation (ASF) under one or more
      12             :  *   contributor license agreements. See the NOTICE file distributed
      13             :  *   with this work for additional information regarding copyright
      14             :  *   ownership. The ASF licenses this file to you under the Apache
      15             :  *   License, Version 2.0 (the "License"); you may not use this file
      16             :  *   except in compliance with the License. You may obtain a copy of
      17             :  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
      18             :  */
      19             : 
      20             : #include <filter/msfilter/msvbahelper.hxx>
      21             : #include <basic/sbx.hxx>
      22             : #include <basic/sbstar.hxx>
      23             : #include <basic/basmgr.hxx>
      24             : #include <basic/sbmod.hxx>
      25             : #include <basic/sbmeth.hxx>
      26             : #include <com/sun/star/document/XDocumentPropertiesSupplier.hpp>
      27             : #include <com/sun/star/document/XDocumentProperties.hpp>
      28             : #include <com/sun/star/script/vba/XVBACompatibility.hpp>
      29             : #include <com/sun/star/lang/XUnoTunnel.hpp>
      30             : #include <com/sun/star/script/ModuleType.hpp>
      31             : #include <cppuhelper/supportsservice.hxx>
      32             : #include <tools/urlobj.hxx>
      33             : #include <osl/file.hxx>
      34             : #include <unotools/pathoptions.hxx>
      35             : 
      36             : #include <com/sun/star/awt/KeyModifier.hpp>
      37             : #include <svtools/acceleratorexecute.hxx>
      38             : #include <com/sun/star/ui/XUIConfigurationManagerSupplier.hpp>
      39             : #include <com/sun/star/ui/XUIConfigurationManager.hpp>
      40             : #include <map>
      41             : 
      42             : using namespace ::com::sun::star;
      43             : 
      44             : namespace ooo {
      45             : namespace vba {
      46             : 
      47           0 : const OUString sUrlPart0( "vnd.sun.star.script:" );
      48           0 : const OUString sUrlPart1( "?language=Basic&location=document" );
      49             : 
      50           0 : OUString makeMacroURL( const OUString& sMacroName )
      51             : {
      52           0 :     return sUrlPart0 + sMacroName + sUrlPart1;
      53             : }
      54             : 
      55           0 : OUString extractMacroName( const OUString& rMacroUrl )
      56             : {
      57           0 :     if( rMacroUrl.startsWith( sUrlPart0 ) && rMacroUrl.endsWith( sUrlPart1 ) )
      58             :     {
      59             :         return rMacroUrl.copy( sUrlPart0.getLength(),
      60           0 :             rMacroUrl.getLength() - sUrlPart0.getLength() - sUrlPart1.getLength() );
      61             :     }
      62           0 :     return OUString();
      63             : }
      64             : 
      65           0 : OUString trimMacroName( const OUString& rMacroName )
      66             : {
      67             :     // the name may contain whitespaces and may be enclosed in apostrophs
      68           0 :     OUString aMacroName = rMacroName.trim();
      69           0 :     sal_Int32 nMacroLen = aMacroName.getLength();
      70           0 :     if( (nMacroLen >= 2) && (aMacroName[ 0 ] == '\'') && (aMacroName[ nMacroLen - 1 ] == '\'') )
      71           0 :         aMacroName = aMacroName.copy( 1, nMacroLen - 2 ).trim();
      72           0 :     return aMacroName;
      73             : }
      74             : 
      75           0 : SfxObjectShell* findShellForUrl( const OUString& sMacroURLOrPath )
      76             : {
      77           0 :     SfxObjectShell* pFoundShell=NULL;
      78           0 :     SfxObjectShell* pShell = SfxObjectShell::GetFirst();
      79           0 :     INetURLObject aObj;
      80           0 :     aObj.SetURL( sMacroURLOrPath );
      81           0 :     bool bIsURL = aObj.GetProtocol() != INET_PROT_NOT_VALID;
      82           0 :     OUString aURL;
      83           0 :     if ( bIsURL )
      84           0 :         aURL = sMacroURLOrPath;
      85             :     else
      86             :     {
      87           0 :         osl::FileBase::getFileURLFromSystemPath( sMacroURLOrPath, aURL );
      88           0 :         aObj.SetURL( aURL );
      89             :     }
      90             :     OSL_TRACE("Trying to find shell for url %s", OUStringToOString( aURL, RTL_TEXTENCODING_UTF8 ).getStr() );
      91           0 :     while ( pShell )
      92             :     {
      93             : 
      94           0 :         uno::Reference< frame::XModel > xModel = pShell->GetModel();
      95             :         // are we searching for a template? if so we have to cater for the
      96             :         // fact that in openoffice a document opened from a template is always
      97             :         // a new document :/
      98           0 :         if ( xModel.is() )
      99             :         {
     100             :             OSL_TRACE("shell 0x%x has model with url %s and we look for %s", pShell
     101             :                 , OUStringToOString( xModel->getURL(), RTL_TEXTENCODING_UTF8 ).getStr()
     102             :                 , OUStringToOString( aURL, RTL_TEXTENCODING_UTF8 ).getStr()
     103             :             );
     104           0 :             OUString aName = xModel->getURL() ;
     105           0 :             if (aName.isEmpty())
     106             :                 {
     107             : 
     108           0 :                     const static OUString sTitle( "Title" );
     109           0 :                     uno::Reference< frame::XFrame > xFrame( xModel->getCurrentController()->getFrame(), uno::UNO_QUERY_THROW );
     110           0 :                     uno::Reference< beans::XPropertySet > xProps( xFrame, uno::UNO_QUERY_THROW );
     111           0 :                     xProps->getPropertyValue(sTitle) >>= aName;
     112           0 :                     sal_Int32 pos = 0;
     113           0 :                     aName = aName.getToken(0,'-',pos);
     114           0 :                     aName = aName.trim();
     115           0 :                     if( sMacroURLOrPath.lastIndexOf( aName ) >= 0 )
     116             :                     {
     117           0 :                         pFoundShell = pShell;
     118           0 :                         break;
     119           0 :                     }
     120             :                 }
     121             : 
     122           0 :             if ( sMacroURLOrPath.endsWithIgnoreAsciiCaseAsciiL( ".dot", 4 ) )
     123             :             {
     124             :                 uno::Reference<document::XDocumentPropertiesSupplier> const
     125           0 :                     xDocPropSupp(xModel, uno::UNO_QUERY);
     126           0 :                 if (xDocPropSupp.is())
     127             :                 {
     128             :                     uno::Reference< document::XDocumentProperties > const
     129           0 :                         xDocProps(xDocPropSupp->getDocumentProperties(),
     130           0 :                                     uno::UNO_QUERY_THROW);
     131           0 :                     OUString sCurrName = xDocProps->getTemplateName();
     132           0 :                     if( sMacroURLOrPath.lastIndexOf( sCurrName ) >= 0 )
     133             :                     {
     134           0 :                         pFoundShell = pShell;
     135           0 :                         break;
     136           0 :                     }
     137           0 :                 }
     138             :             }
     139             :             else
     140             :             {
     141             :                 // sometimes just the name of the document ( without the path
     142             :                 // is used
     143           0 :                 bool bDocNameNoPathMatch = false;
     144           0 :                 if ( !aURL.isEmpty() && aURL.indexOf( '/' ) == -1 )
     145             :                 {
     146           0 :                     sal_Int32 lastSlashIndex = xModel->getURL().lastIndexOf( '/' );
     147           0 :                     if ( lastSlashIndex > -1 )
     148             :                     {
     149           0 :                         bDocNameNoPathMatch = xModel->getURL().copy( lastSlashIndex + 1 ).equals( aURL );
     150           0 :                         if ( !bDocNameNoPathMatch )
     151             :                         {
     152           0 :                             OUString aTmpName = "'" + xModel->getURL().copy( lastSlashIndex + 1 ) + "'";
     153           0 :                             bDocNameNoPathMatch = aTmpName.equals( aURL );
     154             :                         }
     155             :                     }
     156             :                 }
     157             : 
     158           0 :                 if ( aURL.equals( xModel->getURL() ) || bDocNameNoPathMatch )
     159             :                 {
     160           0 :                     pFoundShell = pShell;
     161           0 :                     break;
     162             :                 }
     163           0 :             }
     164             :         }
     165           0 :         pShell = SfxObjectShell::GetNext( *pShell );
     166           0 :     }
     167           0 :     return pFoundShell;
     168             : }
     169             : 
     170             : // sMod can be empty ( but we really need the library to search in )
     171             : // if sMod is empty and a macro is found then sMod is updated
     172             : // if sMod is empty, only standard modules will be searched (no class, document, form modules)
     173           0 : bool hasMacro( SfxObjectShell* pShell, const OUString& sLibrary, OUString& sMod, const OUString& sMacro )
     174             : {
     175           0 :     bool bFound = false;
     176             : 
     177             : #ifdef DISABLE_SCRIPTING
     178             :     (void) pShell;
     179             :     (void) sLibrary;
     180             :     (void) sMod;
     181             :     (void) sMacro;
     182             : #else
     183           0 :     if ( !sLibrary.isEmpty() && !sMacro.isEmpty() )
     184             :     {
     185             :         OSL_TRACE("** Searching for %s.%s in library %s"
     186             :             ,OUStringToOString( sMod, RTL_TEXTENCODING_UTF8 ).getStr()
     187             :             ,OUStringToOString( sMacro, RTL_TEXTENCODING_UTF8 ).getStr()
     188             :             ,OUStringToOString( sLibrary, RTL_TEXTENCODING_UTF8 ).getStr() );
     189           0 :         BasicManager* pBasicMgr = pShell-> GetBasicManager();
     190           0 :         if ( pBasicMgr )
     191             :         {
     192           0 :             StarBASIC* pBasic = pBasicMgr->GetLib( sLibrary );
     193           0 :             if ( !pBasic )
     194             :             {
     195           0 :                 sal_uInt16 nId = pBasicMgr->GetLibId( sLibrary );
     196           0 :                 pBasicMgr->LoadLib( nId );
     197           0 :                 pBasic = pBasicMgr->GetLib( sLibrary );
     198             :             }
     199           0 :             if ( pBasic )
     200             :             {
     201           0 :                 if ( !sMod.isEmpty() ) // we wish to find the macro is a specific module
     202             :                 {
     203           0 :                     SbModule* pModule = pBasic->FindModule( sMod );
     204           0 :                     if ( pModule )
     205             :                     {
     206           0 :                         SbxArray* pMethods = pModule->GetMethods();
     207           0 :                         if ( pMethods )
     208             :                         {
     209           0 :                             SbMethod* pMethod = static_cast< SbMethod* >( pMethods->Find( sMacro, SbxCLASS_METHOD ) );
     210           0 :                             if ( pMethod )
     211           0 :                               bFound = true;
     212             :                         }
     213             :                     }
     214             :                 }
     215           0 :                 else if( SbMethod* pMethod = dynamic_cast< SbMethod* >( pBasic->Find( sMacro, SbxCLASS_METHOD ) ) )
     216             :                 {
     217           0 :                     if( SbModule* pModule = pMethod->GetModule() )
     218             :                     {
     219             :                         // when searching for a macro without module name, do not search in class/document/form modules
     220           0 :                         if( pModule->GetModuleType() == script::ModuleType::NORMAL )
     221             :                         {
     222           0 :                             sMod = pModule->GetName();
     223           0 :                             bFound = true;
     224             :                         }
     225             :                     }
     226             :                 }
     227             :             }
     228             :         }
     229             :     }
     230             : #endif
     231           0 :     return bFound;
     232             : }
     233             : 
     234           0 : OUString getDefaultProjectName( SfxObjectShell* pShell )
     235             : {
     236           0 :     OUString aPrjName;
     237           0 :     if( BasicManager* pBasicMgr = pShell ? pShell->GetBasicManager() : 0 )
     238             :     {
     239           0 :         aPrjName = pBasicMgr->GetName();
     240           0 :         if( aPrjName.isEmpty() )
     241           0 :             aPrjName = "Standard";
     242             :     }
     243           0 :     return aPrjName;
     244             : }
     245             : 
     246           0 : void parseMacro( const OUString& sMacro, OUString& sContainer, OUString& sModule, OUString& sProcedure )
     247             : {
     248           0 :     sal_Int32 nMacroDot = sMacro.lastIndexOf( '.' );
     249             : 
     250           0 :     if ( nMacroDot != -1 )
     251             :     {
     252           0 :         sProcedure = sMacro.copy( nMacroDot + 1 );
     253             : 
     254           0 :         sal_Int32 nContainerDot = sMacro.lastIndexOf( '.',  nMacroDot - 1 );
     255           0 :         if ( nContainerDot != -1 )
     256             :         {
     257           0 :             sModule = sMacro.copy( nContainerDot + 1, nMacroDot - nContainerDot - 1 );
     258           0 :             sContainer = sMacro.copy( 0, nContainerDot );
     259             :         }
     260             :         else
     261           0 :             sModule = sMacro.copy( 0, nMacroDot );
     262             :     }
     263             :     else
     264           0 :        sProcedure = sMacro;
     265           0 : }
     266             : 
     267           0 : OUString resolveVBAMacro( SfxObjectShell* pShell, const OUString& rLibName, const OUString& rModuleName, const OUString& rMacroName )
     268             : {
     269             : #ifdef DISABLE_SCRIPTING
     270             :     (void) pShell;
     271             :     (void) rLibName;
     272             :     (void) rModuleName;
     273             :     (void) rMacroName;
     274             : #else
     275           0 :     if( pShell )
     276             :     {
     277           0 :         OUString aLibName = rLibName.isEmpty() ?  getDefaultProjectName( pShell ) : rLibName ;
     278           0 :         OUString aModuleName = rModuleName;
     279           0 :         if( hasMacro( pShell, aLibName, aModuleName, rMacroName ) )
     280           0 :             return aLibName + "." + aModuleName + "." + rMacroName;
     281             :     }
     282             : #endif
     283           0 :     return OUString();
     284             : }
     285             : 
     286           0 : MacroResolvedInfo resolveVBAMacro( SfxObjectShell* pShell, const OUString& MacroName, bool bSearchGlobalTemplates )
     287             : {
     288             : #ifdef DISABLE_SCRIPTING
     289             :     (void) pShell;
     290             :     (void) MacroName;
     291             :     (void) bSearchGlobalTemplates;
     292             : 
     293             :     return MacroResolvedInfo();
     294             : #else
     295           0 :     if( !pShell )
     296           0 :         return MacroResolvedInfo();
     297             : 
     298             :     // the name may be enclosed in apostrophs
     299           0 :     OUString aMacroName = trimMacroName( MacroName );
     300             : 
     301             :     // parse the macro name
     302           0 :     sal_Int32 nDocSepIndex = aMacroName.indexOf( '!' );
     303           0 :     if( nDocSepIndex > 0 )
     304             :     {
     305             :         // macro specified by document name
     306             :         // find document shell for document name and call ourselves
     307             :         // recursively
     308             : 
     309             :         // assume for now that the document name is *this* document
     310           0 :         OUString sDocUrlOrPath = aMacroName.copy( 0, nDocSepIndex );
     311           0 :         aMacroName = aMacroName.copy( nDocSepIndex + 1 );
     312             :         OSL_TRACE("doc search, current shell is 0x%x", pShell );
     313           0 :         SfxObjectShell* pFoundShell = 0;
     314           0 :         if( bSearchGlobalTemplates )
     315             :         {
     316           0 :             SvtPathOptions aPathOpt;
     317           0 :             OUString aAddinPath = aPathOpt.GetAddinPath();
     318           0 :             if( sDocUrlOrPath.startsWith( aAddinPath ) )
     319           0 :                 pFoundShell = pShell;
     320             :         }
     321           0 :         if( !pFoundShell )
     322           0 :             pFoundShell = findShellForUrl( sDocUrlOrPath );
     323             :         OSL_TRACE("doc search, after find, found shell is 0x%x", pFoundShell );
     324           0 :         return resolveVBAMacro( pFoundShell, aMacroName );
     325             :     }
     326             : 
     327             :     // macro is contained in 'this' document ( or code imported from a template
     328             :     // where that template is a global template or perhaps the template this
     329             :     // document is created from )
     330             : 
     331           0 :     MacroResolvedInfo aRes( pShell );
     332             : 
     333             :     // macro format = Container.Module.Procedure
     334           0 :     OUString sContainer, sModule, sProcedure;
     335           0 :     parseMacro( aMacroName, sContainer, sModule, sProcedure );
     336             : 
     337             : #if 0
     338             :     // As long as service VBAProjectNameProvider isn't supported in the model, disable the createInstance call
     339             :     // (the ServiceNotRegisteredException is wrongly caught in ScModelObj::createInstance)
     340             :     uno::Reference< container::XNameContainer > xPrjNameCache;
     341             :     uno::Reference< lang::XMultiServiceFactory> xSF( pShell->GetModel(), uno::UNO_QUERY);
     342             :     if ( xSF.is() ) try
     343             :     {
     344             :         xPrjNameCache.set( xSF->createInstance( "ooo.vba.VBAProjectNameProvider" ), uno::UNO_QUERY );
     345             :     }
     346             :     catch( const uno::Exception& )    // createInstance may throw
     347             :     {
     348             :     }
     349             : #endif
     350             : 
     351           0 :     std::vector< OUString > sSearchList;
     352             : 
     353           0 :     if ( !sContainer.isEmpty() )
     354             :     {
     355             : // service VBAProjectNameProvider not implemented
     356             : #if 0
     357             :         // get the Project associated with the Container
     358             :         if ( xPrjNameCache.is() )
     359             :         {
     360             :             if ( xPrjNameCache->hasByName( sContainer ) )
     361             :             {
     362             :                 OUString sProject;
     363             :                 xPrjNameCache->getByName( sContainer ) >>= sProject;
     364             :                 sContainer = sProject;
     365             :             }
     366             :         }
     367             : #endif
     368           0 :         sSearchList.push_back( sContainer ); // First Lib to search
     369             :     }
     370             :     else
     371             :     {
     372             :         // Ok, if we have no Container specified then we need to search them in order, this document, template this document created from, global templates,
     373             :         // get the name of Project/Library for 'this' document
     374           0 :             OUString sThisProject( "Standard" );
     375             :             try
     376             :             {
     377           0 :                 uno::Reference< beans::XPropertySet > xProps( pShell->GetModel(), uno::UNO_QUERY_THROW );
     378           0 :                 uno::Reference< script::vba::XVBACompatibility > xVBAMode( xProps->getPropertyValue( "BasicLibraries" ), uno::UNO_QUERY_THROW );
     379           0 :                 sThisProject = xVBAMode->getProjectName();
     380             :             }
     381           0 :             catch( const uno::Exception& /*e*/) {}
     382             : 
     383           0 :         sSearchList.push_back( sThisProject ); // First Lib to search
     384             : 
     385             : // service VBAProjectNameProvider not implemented
     386             : #if 0
     387             :         if ( xPrjNameCache.is() )
     388             :         {
     389             :             // is this document created from a template?
     390             :             uno::Reference< document::XDocumentPropertiesSupplier > const
     391             :                 xDocPropSupp(pShell->GetModel(), uno::UNO_QUERY_THROW);
     392             :             uno::Reference< document::XDocumentProperties > xDocProps( xDocPropSupp->getDocumentProperties(), uno::UNO_QUERY_THROW );
     393             : 
     394             :             OUString sCreatedFrom = xDocProps->getTemplateURL();
     395             :             if ( !sCreatedFrom.isEmpty() )
     396             :             {
     397             :                 INetURLObject aObj;
     398             :                 aObj.SetURL( sCreatedFrom );
     399             :                 bool bIsURL = aObj.GetProtocol() != INET_PROT_NOT_VALID;
     400             :                 OUString aURL;
     401             :                 if ( bIsURL )
     402             :                     aURL = sCreatedFrom;
     403             :                 else
     404             :                 {
     405             :                     osl::FileBase::getFileURLFromSystemPath( sCreatedFrom, aURL );
     406             :                     aObj.SetURL( aURL );
     407             :                 }
     408             :                 sCreatedFrom =  aObj.GetLastName();
     409             :             }
     410             : 
     411             :             sal_Int32 nIndex =  sCreatedFrom.lastIndexOf( '.' );
     412             :             if ( nIndex != -1 )
     413             :                 sCreatedFrom = sCreatedFrom.copy( 0, nIndex );
     414             : 
     415             :             OUString sPrj;
     416             :             if ( !sCreatedFrom.isEmpty() && xPrjNameCache->hasByName( sCreatedFrom ) )
     417             :             {
     418             :                 xPrjNameCache->getByName( sCreatedFrom ) >>= sPrj;
     419             :                 // Make sure we don't double up with this project
     420             :                 if ( !sPrj.equals( sThisProject ) )
     421             :                     sSearchList.push_back( sPrj );
     422             :             }
     423             : 
     424             :             // get list of global template Names
     425             :             uno::Sequence< OUString > sTemplateNames = xPrjNameCache->getElementNames();
     426             :             sal_Int32 nLen = sTemplateNames.getLength();
     427             :             for ( sal_Int32 index = 0; ( bSearchGlobalTemplates && index < nLen ); ++index )
     428             :             {
     429             : 
     430             :                 if ( !sCreatedFrom.equals( sTemplateNames[ index ] ) )
     431             :                 {
     432             :                     if ( xPrjNameCache->hasByName( sTemplateNames[ index ] ) )
     433             :                     {
     434             :                         xPrjNameCache->getByName( sTemplateNames[ index ] ) >>= sPrj;
     435             :                         // Make sure we don't double up with this project
     436             :                         if ( !sPrj.equals( sThisProject ) )
     437             :                             sSearchList.push_back( sPrj );
     438             :                     }
     439             :                 }
     440             : 
     441             :             }
     442             :         }
     443             : #endif
     444             :     }
     445             : 
     446           0 :     std::vector< OUString >::iterator it_end = sSearchList.end();
     447           0 :     for ( std::vector< OUString >::iterator it = sSearchList.begin(); !aRes.mbFound && (it != it_end); ++it )
     448             :     {
     449           0 :         aRes.mbFound = hasMacro( pShell, *it, sModule, sProcedure );
     450           0 :         if ( aRes.mbFound )
     451           0 :             sContainer = *it;
     452             :     }
     453             :     //aRes.msResolvedMacro = sProcedure.Insert( '.', 0 ).Insert( sModule, 0).Insert( '.', 0 ).Insert( sContainer, 0 );
     454           0 :     aRes.msResolvedMacro = sContainer + "." + sModule + "." + sProcedure;
     455             : 
     456           0 :     return aRes;
     457             : #endif
     458             : }
     459             : 
     460             : // Treat the args as possible inouts ( conversion at bottom of method )
     461           0 : bool executeMacro( SfxObjectShell* pShell, const OUString& sMacroName, uno::Sequence< uno::Any >& aArgs, uno::Any& aRet, const uno::Any& /*aCaller*/)
     462             : {
     463             : #ifdef DISABLE_SCRIPTING
     464             :     (void) pShell;
     465             :     (void) sMacroName;
     466             :     (void) aArgs;
     467             :     (void) aRet;
     468             : 
     469             :     return false;
     470             : #else
     471           0 :     bool bRes = false;
     472           0 :     if ( !pShell )
     473           0 :         return bRes;
     474           0 :     OUString sUrl = makeMacroURL( sMacroName );
     475             : 
     476           0 :     uno::Sequence< sal_Int16 > aOutArgsIndex;
     477           0 :     uno::Sequence< uno::Any > aOutArgs;
     478             : 
     479             :     try
     480           0 :     {   ErrCode nErr( ERRCODE_BASIC_INTERNAL_ERROR );
     481           0 :         if ( pShell )
     482             :         {
     483             :             nErr = pShell->CallXScript( sUrl,
     484           0 :                                aArgs, aRet, aOutArgsIndex, aOutArgs, false );
     485           0 :             sal_Int32 nLen = aOutArgs.getLength();
     486             :             // convert any out params to seem like they were inouts
     487           0 :             if ( nLen )
     488             :             {
     489           0 :                 for ( sal_Int32 index=0; index < nLen; ++index )
     490             :                 {
     491           0 :                     sal_Int32 nOutIndex = aOutArgsIndex[ index ];
     492           0 :                     aArgs[ nOutIndex ] = aOutArgs[ index ];
     493             :                 }
     494             :             }
     495             :         }
     496           0 :         bRes = ( nErr == ERRCODE_NONE );
     497             :     }
     498           0 :     catch ( const uno::Exception& )
     499             :     {
     500           0 :        bRes = false;
     501             :     }
     502           0 :     return bRes;
     503             : #endif
     504             : }
     505             : 
     506             : 
     507             : 
     508           0 : uno::Sequence< OUString > VBAMacroResolver_getSupportedServiceNames()
     509             : {
     510           0 :     uno::Sequence< OUString > aServiceNames( 1 );
     511           0 :     aServiceNames[ 0 ] = "com.sun.star.script.vba.VBAMacroResolver";
     512           0 :     return aServiceNames;
     513             : }
     514             : 
     515           0 : OUString VBAMacroResolver_getImplementationName()
     516             : {
     517           0 :     return OUString( "com.sun.star.comp.vba.VBAMacroResolver" );
     518             : }
     519             : 
     520           0 : uno::Reference< uno::XInterface > SAL_CALL VBAMacroResolver_createInstance( const uno::Reference< uno::XComponentContext >& ) throw (uno::Exception)
     521             : {
     522           0 :     return static_cast< ::cppu::OWeakObject* >( new VBAMacroResolver );
     523             : }
     524             : 
     525             : 
     526             : 
     527           0 : VBAMacroResolver::VBAMacroResolver() :
     528           0 :     mpObjShell( 0 )
     529             : {
     530           0 : }
     531             : 
     532           0 : VBAMacroResolver::~VBAMacroResolver()
     533             : {
     534           0 : }
     535             : 
     536             : // com.sun.star.lang.XServiceInfo interface -----------------------------------
     537             : 
     538           0 : OUString SAL_CALL VBAMacroResolver::getImplementationName() throw (uno::RuntimeException, std::exception)
     539             : {
     540           0 :     return VBAMacroResolver_getImplementationName();
     541             : }
     542             : 
     543           0 : sal_Bool SAL_CALL VBAMacroResolver::supportsService( const OUString& rService ) throw (uno::RuntimeException, std::exception)
     544             : {
     545           0 :     return cppu::supportsService(this, rService);
     546             : }
     547             : 
     548           0 : uno::Sequence< OUString > SAL_CALL VBAMacroResolver::getSupportedServiceNames() throw (uno::RuntimeException, std::exception)
     549             : {
     550           0 :     return VBAMacroResolver_getSupportedServiceNames();
     551             : }
     552             : 
     553             : // com.sun.star.lang.XInitialization interface --------------------------------
     554             : 
     555           0 : void SAL_CALL VBAMacroResolver::initialize( const uno::Sequence< uno::Any >& rArgs ) throw (uno::Exception, uno::RuntimeException, std::exception)
     556             : {
     557             :     OSL_ENSURE( rArgs.getLength() < 2, "VBAMacroResolver::initialize - missing arguments" );
     558           0 :     if( rArgs.getLength() < 2 )
     559           0 :         throw uno::RuntimeException();
     560             : 
     561             :     // first argument: document model
     562           0 :     mxModel.set( rArgs[ 0 ], uno::UNO_QUERY_THROW );
     563           0 :     uno::Reference< lang::XUnoTunnel > xUnoTunnel( mxModel, uno::UNO_QUERY_THROW );
     564           0 :     mpObjShell = reinterpret_cast< SfxObjectShell* >( xUnoTunnel->getSomething( SfxObjectShell::getUnoTunnelId() ) );
     565           0 :     if( !mpObjShell )
     566           0 :         throw uno::RuntimeException();
     567             : 
     568             :     // second argument: VBA project name
     569           0 :     if( !(rArgs[ 1 ] >>= maProjectName) || (maProjectName.isEmpty()) )
     570           0 :         throw uno::RuntimeException();
     571           0 : }
     572             : 
     573             : // com.sun.star.script.vba.XVBAMacroResolver interface ------------------------
     574             : 
     575           0 : OUString SAL_CALL VBAMacroResolver::resolveVBAMacroToScriptURL( const OUString& rVBAMacroName ) throw (lang::IllegalArgumentException, uno::RuntimeException, std::exception)
     576             : {
     577           0 :     if( !mpObjShell )
     578           0 :         throw uno::RuntimeException();
     579             : 
     580             :     // the name may be enclosed in apostrophs
     581           0 :     OUString aMacroName = trimMacroName( rVBAMacroName );
     582           0 :     if( aMacroName.isEmpty() )
     583           0 :         throw lang::IllegalArgumentException();
     584             : 
     585             :     // external references not supported here (syntax is "url!macroname" or "[url]!macroname" or "[url]macroname")
     586           0 :     if( (aMacroName[ 0 ] == '[') || (aMacroName.indexOf( '!' ) >= 0) )
     587           0 :         throw lang::IllegalArgumentException();
     588             : 
     589             :     // check if macro name starts with project name, replace with "Standard"
     590             :     // TODO: adjust this when custom VBA project name is supported
     591           0 :     sal_Int32 nDotPos = aMacroName.indexOf( '.' );
     592           0 :     if( (nDotPos == 0) || (nDotPos + 1 == aMacroName.getLength()) )
     593           0 :         throw lang::IllegalArgumentException();
     594           0 :     if( (nDotPos > 0) && aMacroName.matchIgnoreAsciiCase( maProjectName ) )
     595           0 :         aMacroName = aMacroName.copy( nDotPos + 1 );
     596             : 
     597             :     // try to find the macro
     598           0 :     MacroResolvedInfo aInfo = resolveVBAMacro( mpObjShell, aMacroName, false );
     599           0 :     if( !aInfo.mbFound )
     600           0 :         throw lang::IllegalArgumentException();
     601             : 
     602             :     // build and return the script URL
     603           0 :     return makeMacroURL( aInfo.msResolvedMacro );
     604             : }
     605             : 
     606           0 : OUString SAL_CALL VBAMacroResolver::resolveScriptURLtoVBAMacro( const OUString& /*rScriptURL*/ ) throw (lang::IllegalArgumentException, uno::RuntimeException, std::exception)
     607             : {
     608             :     OSL_ENSURE( false, "VBAMacroResolver::resolveScriptURLtoVBAMacro - not implemented" );
     609           0 :     throw uno::RuntimeException();
     610             : }
     611             : 
     612           0 : bool getModifier( char c, sal_uInt16& mod )
     613             : {
     614             :     static const char modifiers[] = "+^%";
     615             :     static const sal_uInt16 KEY_MODS[] = {KEY_SHIFT, KEY_MOD1, KEY_MOD2};
     616             : 
     617           0 :     for ( unsigned int i=0; i<SAL_N_ELEMENTS(KEY_MODS); ++i )
     618             :     {
     619           0 :         if ( c == modifiers[i] )
     620             :         {
     621           0 :             mod = mod | KEY_MODS[ i ];
     622           0 :             return true;
     623             :         }
     624             :     }
     625           0 :     return false;
     626             : }
     627             : 
     628             : typedef std::map< OUString, sal_uInt16 > MSKeyCodeMap;
     629             : 
     630           0 : sal_uInt16 parseChar( char c ) throw ( uno::RuntimeException )
     631             : {
     632           0 :     sal_uInt16 nVclKey = 0;
     633             :     // do we care about locale here for isupper etc. ? probably not
     634           0 :     if ( isalpha( c ) )
     635             :     {
     636           0 :         nVclKey |= ( toupper( c ) - 'A' ) + KEY_A;
     637           0 :         if ( isupper( c ) )
     638           0 :             nVclKey |= KEY_SHIFT;
     639             :     }
     640           0 :     else if ( isdigit( c ) )
     641           0 :         nVclKey |= ( c  - '0' ) + KEY_0;
     642           0 :     else if ( c == '~' ) // special case
     643           0 :         nVclKey = KEY_RETURN;
     644           0 :     else if ( c == ' ' ) // special case
     645           0 :         nVclKey = KEY_SPACE;
     646             :     else // I guess we have a problem ( but not sure if locale specific keys might come into play here )
     647           0 :         throw uno::RuntimeException();
     648           0 :     return nVclKey;
     649             : }
     650             : 
     651             : struct KeyCodeEntry
     652             : {
     653             :    const char* sName;
     654             :    sal_uInt16 nCode;
     655             : };
     656             : 
     657             : KeyCodeEntry aMSKeyCodesData[] = {
     658             :     { "BACKSPACE", KEY_BACKSPACE },
     659             :     { "BS", KEY_BACKSPACE },
     660             :     { "DELETE", KEY_DELETE },
     661             :     { "DEL", KEY_DELETE },
     662             :     { "DOWN", KEY_DOWN },
     663             :     { "UP", KEY_UP },
     664             :     { "LEFT", KEY_LEFT },
     665             :     { "RIGHT", KEY_RIGHT },
     666             :     { "END", KEY_END },
     667             :     { "ESCAPE", KEY_ESCAPE },
     668             :     { "ESC", KEY_ESCAPE },
     669             :     { "HELP", KEY_HELP },
     670             :     { "HOME", KEY_HOME },
     671             :     { "PGDN", KEY_PAGEDOWN },
     672             :     { "PGUP", KEY_PAGEUP },
     673             :     { "INSERT", KEY_INSERT },
     674             :     { "SCROLLLOCK", KEY_SCROLLLOCK },
     675             :     { "NUMLOCK", KEY_NUMLOCK },
     676             :     { "TAB", KEY_TAB },
     677             :     { "F1", KEY_F1 },
     678             :     { "F2", KEY_F2 },
     679             :     { "F3", KEY_F3 },
     680             :     { "F4", KEY_F4 },
     681             :     { "F5", KEY_F5 },
     682             :     { "F6", KEY_F6 },
     683             :     { "F7", KEY_F7 },
     684             :     { "F8", KEY_F8 },
     685             :     { "F9", KEY_F1 },
     686             :     { "F10", KEY_F10 },
     687             :     { "F11", KEY_F11 },
     688             :     { "F12", KEY_F12 },
     689             :     { "F13", KEY_F13 },
     690             :     { "F14", KEY_F14 },
     691             :     { "F15", KEY_F15 },
     692             : };
     693             : 
     694           0 : awt::KeyEvent parseKeyEvent( const OUString& Key ) throw ( uno::RuntimeException )
     695             : {
     696           0 :     static MSKeyCodeMap msKeyCodes;
     697           0 :     if ( msKeyCodes.empty() )
     698             :     {
     699           0 :         for ( unsigned int i = 0; i < SAL_N_ELEMENTS( aMSKeyCodesData ); ++i )
     700             :         {
     701           0 :             msKeyCodes[ OUString::createFromAscii( aMSKeyCodesData[ i ].sName ) ] = aMSKeyCodesData[ i ].nCode;
     702             :         }
     703             :     }
     704           0 :     OUString sKeyCode;
     705           0 :     sal_uInt16 nVclKey = 0;
     706             : 
     707             :     // parse the modifier if any
     708           0 :     for ( int i=0; i<Key.getLength(); ++i )
     709             :     {
     710           0 :         if ( ! getModifier( Key[ i ], nVclKey ) )
     711             :         {
     712           0 :             sKeyCode = Key.copy( i );
     713           0 :             break;
     714             :         }
     715             :     }
     716             : 
     717             :     // check if keycode is surrounded by '{}', if so scoop out the contents
     718             :     // else it should be just one char of ( 'a-z,A-Z,0-9' )
     719           0 :     if ( sKeyCode.getLength() == 1 ) // ( a single char )
     720             :     {
     721           0 :         char c = (char)( sKeyCode[ 0 ] );
     722           0 :         nVclKey |= parseChar( c );
     723             :     }
     724             :     else // key should be enclosed in '{}'
     725             :     {
     726           0 :         if ( sKeyCode.getLength() < 3 ||  !( sKeyCode[0] == '{' && sKeyCode[sKeyCode.getLength() - 1 ] == '}' ) )
     727           0 :             throw uno::RuntimeException();
     728             : 
     729           0 :         sKeyCode = sKeyCode.copy(1, sKeyCode.getLength() - 2 );
     730             : 
     731           0 :         if ( sKeyCode.getLength() == 1 )
     732           0 :             nVclKey |= parseChar( (char)( sKeyCode[ 0 ] ) );
     733             :         else
     734             :         {
     735           0 :             MSKeyCodeMap::iterator it = msKeyCodes.find( sKeyCode );
     736           0 :             if ( it == msKeyCodes.end() ) // unknown or unsupported
     737           0 :                 throw uno::RuntimeException();
     738           0 :             nVclKey |= it->second;
     739             :         }
     740             :     }
     741             : 
     742           0 :     awt::KeyEvent aKeyEvent = svt::AcceleratorExecute::st_VCLKey2AWTKey( KeyCode( nVclKey ) );
     743           0 :     return aKeyEvent;
     744             : }
     745             : 
     746           0 : void applyShortCutKeyBinding ( const uno::Reference< frame::XModel >& rxModel, const awt::KeyEvent& rKeyEvent, const OUString& rMacroName ) throw (uno::RuntimeException)
     747             : {
     748           0 :     OUString MacroName( rMacroName );
     749           0 :     if ( !MacroName.isEmpty() )
     750             :     {
     751           0 :         OUString aMacroName = MacroName.trim();
     752           0 :         if( aMacroName.startsWith("!") )
     753           0 :             MacroName = aMacroName.copy(1).trim();
     754           0 :         SfxObjectShell* pShell = NULL;
     755           0 :         if ( rxModel.is() )
     756             :         {
     757           0 :             uno::Reference< lang::XUnoTunnel >  xObjShellTunnel( rxModel, uno::UNO_QUERY_THROW );
     758           0 :             pShell = reinterpret_cast<SfxObjectShell*>( xObjShellTunnel->getSomething(SfxObjectShell::getUnoTunnelId()));
     759           0 :             if ( !pShell )
     760           0 :                 throw uno::RuntimeException();
     761             :         }
     762           0 :         MacroResolvedInfo aMacroInfo = resolveVBAMacro( pShell, aMacroName );
     763           0 :         if( !aMacroInfo.mbFound )
     764           0 :             throw uno::RuntimeException( "The procedure doesn't exist", uno::Reference< uno::XInterface >() );
     765           0 :        MacroName = aMacroInfo.msResolvedMacro;
     766             :     }
     767           0 :     uno::Reference< ui::XUIConfigurationManagerSupplier > xCfgSupplier(rxModel, uno::UNO_QUERY_THROW);
     768           0 :     uno::Reference< ui::XUIConfigurationManager > xCfgMgr = xCfgSupplier->getUIConfigurationManager();
     769             : 
     770           0 :     uno::Reference< ui::XAcceleratorConfiguration > xAcc( xCfgMgr->getShortCutManager(), uno::UNO_QUERY_THROW );
     771           0 :     if ( MacroName.isEmpty() )
     772             :         // I believe this should really restore the [application] default. Since
     773             :         // afaik we don't actually setup application default bindings on import
     774             :         // we don't even know what the 'default' would be for this key
     775           0 :         xAcc->removeKeyEvent( rKeyEvent );
     776             :     else
     777           0 :         xAcc->setKeyEvent( rKeyEvent, ooo::vba::makeMacroURL( MacroName ) );
     778             : 
     779           0 : }
     780             : 
     781             : 
     782             : } // namespace vba
     783           0 : } // namespace ooo
     784             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
     785             : 

Generated by: LCOV version 1.10