LCOV - code coverage report
Current view: top level - oox/source/ole - vbamodule.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 122 184 66.3 %
Date: 2012-08-25 Functions: 15 21 71.4 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 140 345 40.6 %

           Branch data     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 "oox/ole/vbamodule.hxx"
      21                 :            : #include <boost/unordered_map.hpp>
      22                 :            : #include <com/sun/star/container/XNameContainer.hpp>
      23                 :            : #include <com/sun/star/container/XIndexContainer.hpp>
      24                 :            : #include <com/sun/star/script/ModuleInfo.hpp>
      25                 :            : #include <com/sun/star/script/ModuleType.hpp>
      26                 :            : #include <com/sun/star/script/vba/XVBAModuleInfo.hpp>
      27                 :            : #include <com/sun/star/awt/KeyEvent.hpp>
      28                 :            : #include <cppuhelper/implbase1.hxx>
      29                 :            : #include <filter/msfilter/msvbahelper.hxx>
      30                 :            : #include "oox/helper/binaryinputstream.hxx"
      31                 :            : #include "oox/helper/storagebase.hxx"
      32                 :            : #include "oox/helper/textinputstream.hxx"
      33                 :            : #include "oox/ole/vbahelper.hxx"
      34                 :            : #include "oox/ole/vbainputstream.hxx"
      35                 :            : 
      36                 :            : namespace oox {
      37                 :            : namespace ole {
      38                 :            : 
      39                 :            : // ============================================================================
      40                 :            : 
      41                 :            : using namespace ::com::sun::star::lang;
      42                 :            : using namespace ::com::sun::star::script::vba;
      43                 :            : using namespace ::com::sun::star::uno;
      44                 :            : using namespace ::com::sun::star;
      45                 :            : 
      46                 :            : using ::rtl::OUString;
      47                 :            : using ::rtl::OUStringBuffer;
      48                 :            : using ::com::sun::star::awt::KeyEvent;
      49                 :            : // ============================================================================
      50                 :            : typedef ::cppu::WeakImplHelper1< container::XIndexContainer > OleIdToNameContainer_BASE;
      51                 :            : typedef boost::unordered_map< sal_Int32, rtl::OUString >  ObjIdToName;
      52                 :            : 
      53 [ +  - ][ +  - ]:         10 : class OleIdToNameContainer : public OleIdToNameContainer_BASE
                 [ -  + ]
      54                 :            : {
      55                 :            :     ObjIdToName ObjIdToNameHash;
      56                 :            :     ::osl::Mutex m_aMutex;
      57                 :         33 :     bool hasByIndex( ::sal_Int32 Index )
      58                 :            :     {
      59         [ +  - ]:         33 :         ::osl::MutexGuard aGuard( m_aMutex );
      60 [ +  - ][ +  - ]:         33 :         return ( ObjIdToNameHash.find( Index ) != ObjIdToNameHash.end() );
                 [ +  - ]
      61                 :            :     }
      62                 :            : public:
      63 [ +  - ][ +  - ]:          5 :     OleIdToNameContainer() {}
      64                 :            :     // XIndexContainer Methods
      65                 :         11 :     virtual void SAL_CALL insertByIndex( ::sal_Int32 Index, const Any& Element ) throw (IllegalArgumentException, IndexOutOfBoundsException, WrappedTargetException, RuntimeException)
      66                 :            :     {
      67         [ +  - ]:         11 :         ::osl::MutexGuard aGuard( m_aMutex );
      68                 :         11 :         rtl::OUString sOleName;
      69         [ -  + ]:         11 :         if ( !( Element >>= sOleName ) )
      70         [ #  # ]:          0 :             throw IllegalArgumentException();
      71 [ +  - ][ +  - ]:         11 :         ObjIdToNameHash[ Index ] = sOleName;
      72                 :         11 :     }
      73                 :          0 :     virtual void SAL_CALL removeByIndex( ::sal_Int32 Index ) throw (IndexOutOfBoundsException, WrappedTargetException, RuntimeException)
      74                 :            :     {
      75         [ #  # ]:          0 :         ::osl::MutexGuard aGuard( m_aMutex );
      76 [ #  # ][ #  # ]:          0 :         if ( !hasByIndex( Index ) )
      77         [ #  # ]:          0 :             throw IndexOutOfBoundsException();
      78 [ #  # ][ #  # ]:          0 :         ObjIdToNameHash.erase( ObjIdToNameHash.find( Index ) );
                 [ #  # ]
      79                 :          0 :     }
      80                 :            :     // XIndexReplace Methods
      81                 :          0 :     virtual void SAL_CALL replaceByIndex( ::sal_Int32 Index, const Any& Element ) throw (IllegalArgumentException, IndexOutOfBoundsException, WrappedTargetException, RuntimeException)
      82                 :            :     {
      83         [ #  # ]:          0 :         ::osl::MutexGuard aGuard( m_aMutex );
      84 [ #  # ][ #  # ]:          0 :         if ( !hasByIndex( Index ) )
      85         [ #  # ]:          0 :             throw IndexOutOfBoundsException();
      86                 :          0 :         rtl::OUString sOleName;
      87         [ #  # ]:          0 :         if ( !( Element >>= sOleName ) )
      88         [ #  # ]:          0 :             throw IllegalArgumentException();
      89 [ #  # ][ #  # ]:          0 :         ObjIdToNameHash[ Index ] = sOleName;
      90                 :          0 :     }
      91                 :            :     // XIndexAccess Methods
      92                 :          0 :     virtual ::sal_Int32 SAL_CALL getCount(  ) throw (RuntimeException)
      93                 :            :     {
      94         [ #  # ]:          0 :         ::osl::MutexGuard aGuard( m_aMutex );
      95         [ #  # ]:          0 :         return ObjIdToNameHash.size();
      96                 :            :     }
      97                 :         33 :     virtual Any SAL_CALL getByIndex( ::sal_Int32 Index ) throw (IndexOutOfBoundsException, WrappedTargetException, RuntimeException)
      98                 :            :     {
      99         [ +  - ]:         33 :         ::osl::MutexGuard aGuard( m_aMutex );
     100 [ +  - ][ -  + ]:         33 :         if ( !hasByIndex( Index ) )
     101         [ #  # ]:          0 :             throw IndexOutOfBoundsException();
     102 [ +  - ][ +  - ]:         33 :         return makeAny( ObjIdToNameHash[ Index ] );
                 [ +  - ]
     103                 :            :     }
     104                 :            :     // XElementAccess Methods
     105                 :          0 :     virtual Type SAL_CALL getElementType(  ) throw (RuntimeException)
     106                 :            :     {
     107                 :          0 :         return ::getCppuType( static_cast< const ::rtl::OUString* >( 0 ) );
     108                 :            :     }
     109                 :          0 :     virtual ::sal_Bool SAL_CALL hasElements(  ) throw (RuntimeException)
     110                 :            :     {
     111         [ #  # ]:          0 :         ::osl::MutexGuard aGuard( m_aMutex );
     112 [ #  # ][ #  # ]:          0 :         return ( getCount() > 0 );
     113                 :            :     }
     114                 :            : };
     115                 :            : 
     116                 :            :  // ============================================================================
     117                 :            : 
     118                 :         65 : VbaModule::VbaModule( const Reference< XComponentContext >& rxContext,
     119                 :            :                       const Reference< frame::XModel >& rxDocModel,
     120                 :            :                       const OUString& rName, rtl_TextEncoding eTextEnc, bool bExecutable ) :
     121                 :            :     mxContext( rxContext ),
     122                 :            :     mxDocModel( rxDocModel ),
     123                 :            :     maName( rName ),
     124                 :            :     meTextEnc( eTextEnc ),
     125                 :            :     mnType( script::ModuleType::UNKNOWN ),
     126                 :            :     mnOffset( SAL_MAX_UINT32 ),
     127                 :            :     mbReadOnly( false ),
     128                 :            :     mbPrivate( false ),
     129                 :         65 :     mbExecutable( bExecutable )
     130                 :            : {
     131                 :         65 : }
     132                 :            : 
     133                 :         65 : void VbaModule::importDirRecords( BinaryInputStream& rDirStrm )
     134                 :            : {
     135                 :         65 :     sal_uInt16 nRecId = 0;
     136         [ +  - ]:         65 :     StreamDataSequence aRecData;
     137 [ +  - ][ +  - ]:        620 :     while( VbaHelper::readDirRecord( nRecId, aRecData, rDirStrm ) && (nRecId != VBA_ID_MODULEEND) )
         [ +  + ][ +  + ]
     138                 :            :     {
     139         [ +  - ]:        555 :         SequenceInputStream aRecStrm( aRecData );
     140                 :        555 :         sal_Int32 nRecSize = aRecData.getLength();
     141   [ -  +  +  +  :        555 :         switch( nRecId )
          +  +  +  +  +  
             +  +  -  -  
                      - ]
     142                 :            :         {
     143                 :            : #define OOX_ENSURE_RECORDSIZE( cond ) OSL_ENSURE( cond, "VbaModule::importDirRecords - invalid record size" )
     144                 :            :             case VBA_ID_MODULENAME:
     145                 :            :                 OSL_FAIL( "VbaModule::importDirRecords - unexpected MODULENAME record" );
     146         [ #  # ]:          0 :                 maName = aRecStrm.readCharArrayUC( nRecSize, meTextEnc );
     147                 :          0 :             break;
     148                 :            :             case VBA_ID_MODULENAMEUNICODE:
     149                 :         35 :             break;
     150                 :            :             case VBA_ID_MODULESTREAMNAME:
     151         [ +  - ]:         65 :                 maStreamName = aRecStrm.readCharArrayUC( nRecSize, meTextEnc );
     152                 :            :                 // Actually the stream name seems the best name to use
     153                 :            :                 // the VBA_ID_MODULENAME name can sometimes be the wrong case
     154                 :         65 :                 maName = maStreamName;
     155                 :         65 :             break;
     156                 :            :             case VBA_ID_MODULESTREAMNAMEUNICODE:
     157                 :         65 :             break;
     158                 :            :             case VBA_ID_MODULEDOCSTRING:
     159         [ +  - ]:         65 :                 maDocString = aRecStrm.readCharArrayUC( nRecSize, meTextEnc );
     160                 :         65 :             break;
     161                 :            :             case VBA_ID_MODULEDOCSTRINGUNICODE:
     162                 :         65 :             break;
     163                 :            :             case VBA_ID_MODULEOFFSET:
     164                 :            :                 OOX_ENSURE_RECORDSIZE( nRecSize == 4 );
     165         [ +  - ]:         65 :                 aRecStrm >> mnOffset;
     166                 :         65 :             break;
     167                 :            :             case VBA_ID_MODULEHELPCONTEXT:
     168                 :            :                 OOX_ENSURE_RECORDSIZE( nRecSize == 4 );
     169                 :         65 :             break;
     170                 :            :             case VBA_ID_MODULECOOKIE:
     171                 :            :                 OOX_ENSURE_RECORDSIZE( nRecSize == 2 );
     172                 :         65 :             break;
     173                 :            :             case VBA_ID_MODULETYPEPROCEDURAL:
     174                 :            :                 OOX_ENSURE_RECORDSIZE( nRecSize == 0 );
     175                 :            :                 OSL_ENSURE( mnType == script::ModuleType::UNKNOWN, "VbaModule::importDirRecords - multiple module type records" );
     176                 :         10 :                 mnType = script::ModuleType::NORMAL;
     177                 :         10 :             break;
     178                 :            :             case VBA_ID_MODULETYPEDOCUMENT:
     179                 :            :                 OOX_ENSURE_RECORDSIZE( nRecSize == 0 );
     180                 :            :                 OSL_ENSURE( mnType == script::ModuleType::UNKNOWN, "VbaModule::importDirRecords - multiple module type records" );
     181                 :         55 :                 mnType = script::ModuleType::DOCUMENT;
     182                 :         55 :             break;
     183                 :            :             case VBA_ID_MODULEREADONLY:
     184                 :            :                 OOX_ENSURE_RECORDSIZE( nRecSize == 0 );
     185                 :          0 :                 mbReadOnly = true;
     186                 :          0 :             break;
     187                 :            :             case VBA_ID_MODULEPRIVATE:
     188                 :            :                 OOX_ENSURE_RECORDSIZE( nRecSize == 0 );
     189                 :          0 :                 mbPrivate = true;
     190                 :          0 :             break;
     191                 :            :             default:
     192                 :            :                 OSL_FAIL( "VbaModule::importDirRecords - unknown module record" );
     193                 :            : #undef OOX_ENSURE_RECORDSIZE
     194                 :            :         }
     195         [ +  - ]:        555 :     }
     196                 :            :     OSL_ENSURE( !maName.isEmpty(), "VbaModule::importDirRecords - missing module name" );
     197                 :            :     OSL_ENSURE( !maStreamName.isEmpty(), "VbaModule::importDirRecords - missing module stream name" );
     198                 :            :     OSL_ENSURE( mnType != script::ModuleType::UNKNOWN, "VbaModule::importDirRecords - missing module type" );
     199         [ +  - ]:         65 :     OSL_ENSURE( mnOffset < SAL_MAX_UINT32, "VbaModule::importDirRecords - missing module stream offset" );
     200                 :         65 : }
     201                 :            : 
     202                 :         65 : void VbaModule::createAndImportModule( StorageBase& rVbaStrg,
     203                 :            :                                        const Reference< container::XNameContainer >& rxBasicLib,
     204                 :            :                                        const Reference< container::XNameAccess >& rxDocObjectNA,
     205                 :            :                                        const Reference< container::XNameContainer >& rxOleNameOverrides ) const
     206                 :            : {
     207         [ +  - ]:         65 :     OUString aVBASourceCode = readSourceCode( rVbaStrg, rxOleNameOverrides );
     208         [ +  - ]:         65 :     createModule( aVBASourceCode, rxBasicLib, rxDocObjectNA );
     209                 :         65 : }
     210                 :            : 
     211                 :          0 : void VbaModule::createEmptyModule( const Reference< container::XNameContainer >& rxBasicLib,
     212                 :            :                                    const Reference< container::XNameAccess >& rxDocObjectNA ) const
     213                 :            : {
     214         [ #  # ]:          0 :     createModule( OUString(), rxBasicLib, rxDocObjectNA );
     215                 :          0 : }
     216                 :            : 
     217                 :         65 : OUString VbaModule::readSourceCode( StorageBase& rVbaStrg, const Reference< container::XNameContainer >& rxOleNameOverrides ) const
     218                 :            : {
     219                 :         65 :     OUStringBuffer aSourceCode;
     220 [ +  - ][ +  - ]:         65 :     const static rtl::OUString sUnmatchedRemovedTag( RTL_CONSTASCII_USTRINGPARAM( "Rem removed unmatched Sub/End: " ) );
         [ #  # ][ +  + ]
     221 [ +  - ][ +  - ]:         65 :     if( !maStreamName.isEmpty() && (mnOffset != SAL_MAX_UINT32) )
                 [ +  - ]
     222                 :            :     {
     223 [ +  - ][ +  - ]:         65 :         BinaryXInputStream aInStrm( rVbaStrg.openInputStream( maStreamName ), true );
     224                 :            :         OSL_ENSURE( !aInStrm.isEof(), "VbaModule::readSourceCode - cannot open module stream" );
     225                 :            :         // skip the 'performance cache' stored before the actual source code
     226         [ +  - ]:         65 :         aInStrm.seek( mnOffset );
     227                 :            :         // if stream is still valid, load the source code
     228         [ +  - ]:         65 :         if( !aInStrm.isEof() )
     229                 :            :         {
     230                 :            :             // decompression starts at current stream position of aInStrm
     231         [ +  - ]:         65 :             VbaInputStream aVbaStrm( aInStrm );
     232                 :            :             // load the source code line-by-line, with some more processing
     233         [ +  - ]:         65 :             TextInputStream aVbaTextStrm( mxContext, aVbaStrm, meTextEnc );
     234                 :            : 
     235                 :            :             struct ProcedurePair
     236                 :            :             {
     237                 :            :                 bool bInProcedure;
     238                 :            :                 sal_uInt32 nPos;
     239                 :         65 :                 ProcedurePair() : bInProcedure( false ), nPos( 0 ) {};
     240                 :         65 :             } procInfo;
     241                 :            : 
     242 [ +  - ][ +  + ]:       1857 :             while( !aVbaTextStrm.isEof() )
     243                 :            :             {
     244         [ +  - ]:       1792 :                 OUString aCodeLine = aVbaTextStrm.readLine();
     245         [ +  + ]:       1792 :                 if( aCodeLine.matchAsciiL( RTL_CONSTASCII_STRINGPARAM( "Attribute " ) ) )
     246                 :            :                 {
     247                 :            :                     // attribute
     248                 :        434 :                     int index = aCodeLine.indexOf( ".VB_ProcData.VB_Invoke_Func = " );
     249         [ -  + ]:        434 :                     if ( index != -1 )
     250                 :            :                     {
     251                 :            :                         // format is
     252                 :            :                         //    'Attribute Procedure.VB_ProcData.VB_Invoke_Func = "*\n14"'
     253                 :            :                         //    where 'Procedure' is the procedure name and '*' is the shortcut key
     254                 :            :                         // note: his is only relevant for Excel, seems that
     255                 :            :                         // word doesn't store the shortcut in the module
     256                 :            :                         // attributes
     257                 :          0 :                         int nSpaceIndex = aCodeLine.indexOf(' ');
     258                 :          0 :                         rtl::OUString sProc = aCodeLine.copy( nSpaceIndex + 1, index - nSpaceIndex - 1);
     259                 :            :                         // for Excel short cut key seems limited to cntrl+'a-z, A-Z'
     260                 :          0 :                         rtl::OUString sKey = aCodeLine.copy( aCodeLine.lastIndexOf("= ") + 3, 1 );
     261                 :            :                         // only alpha key valid for key shortcut, however the api will accept other keys
     262         [ #  # ]:          0 :                         if ( !isalpha( (char)sKey[ 0 ] ) )
     263                 :            :                         {
     264                 :            :                             // cntrl modifier is explicit ( but could be cntrl+shift ), parseKeyEvent
     265                 :            :                             // will handle and uppercase letter appropriately
     266                 :          0 :                             rtl::OUString sApiKey = "^";
     267                 :          0 :                             sApiKey += sKey;
     268                 :            :                             try
     269                 :            :                             {
     270         [ #  # ]:          0 :                                 KeyEvent aKeyEvent = ooo::vba::parseKeyEvent( sApiKey );
     271 [ #  # ][ #  # ]:          0 :                                 ooo::vba::applyShortCutKeyBinding( mxDocModel, aKeyEvent, sProc );
                 [ #  # ]
     272                 :            :                             }
     273         [ #  # ]:          0 :                             catch (const Exception&)
     274                 :            :                             {
     275                 :          0 :                             }
     276                 :          0 :                         }
     277                 :            :                     }
     278                 :            :                     else
     279         [ +  - ]:        434 :                         extractOleOverrideFromAttr( aCodeLine, rxOleNameOverrides );
     280                 :            :                 }
     281                 :            :                 else
     282                 :            :                 {
     283                 :            :                     // Hack here to weed out any unmatched End Sub / Sub Foo statements.
     284                 :            :                     // The behaviour of the vba ide practically guarantees the case and
     285                 :            :                     // spacing of Sub statement(s). However, indentation can be arbitrary hence
     286                 :            :                     // the trim.
     287                 :       1358 :                     rtl::OUString trimLine( aCodeLine.trim() );
     288 [ +  + ][ +  -  :       6725 :                     if ( mbExecutable && (
          +  +  +  -  +  
                +  -  + ]
     289                 :       1358 :                       trimLine.matchAsciiL( RTL_CONSTASCII_STRINGPARAM("Sub ") )         ||
     290                 :       1344 :                       trimLine.matchAsciiL( RTL_CONSTASCII_STRINGPARAM("Public Sub ") )  ||
     291                 :       1344 :                       trimLine.matchAsciiL( RTL_CONSTASCII_STRINGPARAM("Private Sub ") ) ||
     292                 :       1321 :                       trimLine.matchAsciiL( RTL_CONSTASCII_STRINGPARAM("Static Sub ") ) ) )
     293                 :            :                     {
     294                 :            :                         // this should never happen, basic doesn't support nested procedures
     295                 :            :                         // first Sub Foo must be bogus
     296         [ -  + ]:         37 :                         if ( procInfo.bInProcedure )
     297                 :            :                         {
     298                 :            :                             // comment out the line
     299         [ #  # ]:          0 :                             aSourceCode.insert( procInfo.nPos, sUnmatchedRemovedTag );
     300                 :            :                             // mark location of this Sub
     301                 :          0 :                             procInfo.nPos = aSourceCode.getLength();
     302                 :            :                         }
     303                 :            :                         else
     304                 :            :                         {
     305                 :         37 :                             procInfo.bInProcedure = true;
     306                 :         37 :                             procInfo.nPos = aSourceCode.getLength();
     307                 :            :                         }
     308                 :            :                     }
     309 [ +  - ][ +  + ]:       1321 :                     else if ( mbExecutable && aCodeLine.trim().matchAsciiL( RTL_CONSTASCII_STRINGPARAM("End Sub")) )
         [ +  - ][ +  + ]
     310                 :            :                     {
     311                 :            :                         // un-matched End Sub
     312         [ -  + ]:         37 :                         if ( !procInfo.bInProcedure )
     313                 :            :                         {
     314         [ #  # ]:          0 :                             aSourceCode.append( sUnmatchedRemovedTag );
     315                 :            :                         }
     316                 :            :                         else
     317                 :            :                         {
     318                 :         37 :                             procInfo.bInProcedure = false;
     319                 :         37 :                             procInfo.nPos = 0;
     320                 :            :                         }
     321                 :            :                     }
     322                 :            :                     // normal source code line
     323         [ -  + ]:       1358 :                     if( !mbExecutable )
     324         [ #  # ]:          0 :                         aSourceCode.appendAscii( RTL_CONSTASCII_STRINGPARAM( "Rem " ) );
     325 [ +  - ][ +  - ]:       1358 :                     aSourceCode.append( aCodeLine ).append( sal_Unicode( '\n' ) );
     326                 :            :                 }
     327 [ +  - ][ +  - ]:       1857 :             }
     328         [ +  - ]:         65 :         }
     329                 :            :     }
     330         [ +  - ]:         65 :     return aSourceCode.makeStringAndClear();
     331                 :            : }
     332                 :            : 
     333                 :        434 : void VbaModule::extractOleOverrideFromAttr( const OUString& rAttribute,
     334                 :            :                                             const Reference< container::XNameContainer >& rxOleNameOverrides ) const
     335                 :            : {
     336                 :            :     // format of the attribute we are interested in is
     337                 :            :     // Attribute VB_Control = "ControlName", intString, MSForms, ControlTypeAsString
     338                 :            :     // e.g.
     339                 :            :     // Attribute VB_Control = "CommandButton1, 201, 19, MSForms, CommandButton"
     340         [ +  - ]:        434 :     OUString sControlAttribute = CREATE_OUSTRING( "Attribute VB_Control = \"" );
     341 [ +  - ][ +  + ]:        434 :     if ( rxOleNameOverrides.is() && rAttribute.indexOf( sControlAttribute ) !=  -1 )
                 [ +  + ]
     342                 :            :     {
     343                 :         11 :         OUString sRest = rAttribute.copy( sControlAttribute.getLength() );
     344                 :         11 :         sal_Int32 nPos = sRest.indexOf( ',' );
     345                 :         11 :         OUString sCntrlName = sRest.copy( 0, nPos );
     346                 :            : 
     347                 :         11 :         sal_Int32 nCntrlId = sRest.copy( nPos + 1 ).copy( 0, sRest.indexOf( ',', nPos + 1) ).toInt32();
     348                 :            :         OSL_TRACE("In module %s, assiging %d controlname %s",
     349                 :            :             rtl::OUStringToOString( maName, RTL_TEXTENCODING_UTF8 ).getStr(), nCntrlId,
     350                 :            :             rtl::OUStringToOString( sCntrlName, RTL_TEXTENCODING_UTF8 ).getStr() );
     351 [ +  - ][ +  + ]:         11 :         if ( !rxOleNameOverrides->hasByName( maName ) )
                 [ +  - ]
     352 [ +  - ][ +  - ]:          5 :             rxOleNameOverrides->insertByName( maName, Any( Reference< container::XIndexContainer> ( new OleIdToNameContainer ) ) );
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
     353                 :         11 :         Reference< container::XIndexContainer > xIdToOleName;
     354 [ +  - ][ +  - ]:         11 :         if ( rxOleNameOverrides->getByName( maName ) >>= xIdToOleName )
         [ +  - ][ +  - ]
     355 [ +  - ][ +  - ]:         11 :             xIdToOleName->insertByIndex( nCntrlId, makeAny( sCntrlName ) );
                 [ +  - ]
     356                 :        434 :     }
     357                 :        434 : }
     358                 :            : 
     359                 :         65 : void VbaModule::createModule( const OUString& rVBASourceCode,
     360                 :            :                               const Reference< container::XNameContainer >& rxBasicLib,
     361                 :            :                               const Reference< container::XNameAccess >& rxDocObjectNA ) const
     362                 :            : {
     363         [ +  - ]:         65 :     if( maName.isEmpty() )
     364                 :         65 :         return;
     365                 :            : 
     366                 :            :     // prepare the Basic module
     367         [ +  - ]:         65 :     script::ModuleInfo aModuleInfo;
     368                 :         65 :     aModuleInfo.ModuleType = mnType;
     369                 :         65 :     OUStringBuffer aSourceCode;
     370         [ +  - ]:         65 :     aSourceCode.appendAscii( RTL_CONSTASCII_STRINGPARAM( "Rem Attribute VBA_ModuleType=" ) );
     371   [ +  -  -  +  :         65 :     switch( mnType )
                      - ]
     372                 :            :     {
     373                 :            :         case script::ModuleType::NORMAL:
     374         [ +  - ]:         10 :             aSourceCode.appendAscii( RTL_CONSTASCII_STRINGPARAM( "VBAModule" ) );
     375                 :         10 :         break;
     376                 :            :         case script::ModuleType::CLASS:
     377         [ #  # ]:          0 :             aSourceCode.appendAscii( RTL_CONSTASCII_STRINGPARAM( "VBAClassModule" ) );
     378                 :          0 :         break;
     379                 :            :         case script::ModuleType::FORM:
     380         [ #  # ]:          0 :             aSourceCode.appendAscii( RTL_CONSTASCII_STRINGPARAM( "VBAFormModule" ) );
     381                 :            :             // hack from old filter, document Basic should know the XModel, but it doesn't
     382         [ #  # ]:          0 :             aModuleInfo.ModuleObject.set( mxDocModel, UNO_QUERY );
     383                 :          0 :         break;
     384                 :            :         case script::ModuleType::DOCUMENT:
     385         [ +  - ]:         55 :             aSourceCode.appendAscii( RTL_CONSTASCII_STRINGPARAM( "VBADocumentModule" ) );
     386                 :            :             // get the VBA implementation object associated to the document module
     387         [ +  + ]:         55 :             if( rxDocObjectNA.is() ) try
     388                 :            :             {
     389 [ +  - ][ +  - ]:         16 :                 aModuleInfo.ModuleObject.set( rxDocObjectNA->getByName( maName ), UNO_QUERY );
         [ +  - ][ #  # ]
     390                 :            :             }
     391         [ #  # ]:          0 :             catch (const Exception&)
     392                 :            :             {
     393                 :            :             }
     394                 :         55 :         break;
     395                 :            :         default:
     396         [ #  # ]:          0 :             aSourceCode.appendAscii( RTL_CONSTASCII_STRINGPARAM( "VBAUnknown" ) );
     397                 :            :     }
     398         [ +  - ]:         65 :     aSourceCode.append( sal_Unicode( '\n' ) );
     399         [ +  - ]:         65 :     if( mbExecutable )
     400                 :            :     {
     401         [ +  - ]:         65 :         aSourceCode.appendAscii( RTL_CONSTASCII_STRINGPARAM( "Option VBASupport 1\n" ) );
     402         [ -  + ]:         65 :         if( mnType == script::ModuleType::CLASS )
     403         [ #  # ]:          0 :             aSourceCode.appendAscii( RTL_CONSTASCII_STRINGPARAM( "Option ClassModule\n" ) );
     404                 :            :     }
     405                 :            :     else
     406                 :            :     {
     407                 :            :         // add a subroutine named after the module itself
     408         [ #  # ]:          0 :         aSourceCode.appendAscii( RTL_CONSTASCII_STRINGPARAM( "Sub " ) ).
     409 [ #  # ][ #  # ]:          0 :             append( maName.replace( ' ', '_' ) ).append( sal_Unicode( '\n' ) );
     410                 :            :     }
     411                 :            : 
     412                 :            :     // append passed VBA source code
     413         [ +  - ]:         65 :     aSourceCode.append( rVBASourceCode );
     414                 :            : 
     415                 :            :     // close the subroutine named after the module
     416         [ -  + ]:         65 :     if( !mbExecutable )
     417         [ #  # ]:          0 :         aSourceCode.appendAscii( RTL_CONSTASCII_STRINGPARAM( "End Sub\n" ) );
     418                 :            : 
     419                 :            :     // insert extended module info
     420                 :            :     try
     421                 :            :     {
     422         [ +  - ]:         65 :         Reference< XVBAModuleInfo > xVBAModuleInfo( rxBasicLib, UNO_QUERY_THROW );
     423 [ +  - ][ +  - ]:         65 :         xVBAModuleInfo->insertModuleInfo( maName, aModuleInfo );
                 [ #  # ]
     424                 :            :     }
     425         [ #  # ]:          0 :     catch (const Exception&)
     426                 :            :     {
     427                 :            :     }
     428                 :            : 
     429                 :            :     // insert the module into the passed Basic library
     430                 :            :     try
     431                 :            :     {
     432 [ +  - ][ +  - ]:         65 :         rxBasicLib->insertByName( maName, Any( aSourceCode.makeStringAndClear() ) );
         [ +  - ][ +  - ]
                 [ #  # ]
     433                 :            :     }
     434         [ #  # ]:          0 :     catch (const Exception&)
     435                 :            :     {
     436                 :            :         OSL_FAIL( "VbaModule::createModule - cannot insert module into library" );
     437         [ +  - ]:         65 :     }
     438                 :            : }
     439                 :            : 
     440                 :            : // ============================================================================
     441                 :            : 
     442                 :            : } // namespace ole
     443 [ +  - ][ +  - ]:        285 : } // namespace oox
     444                 :            : 
     445                 :            : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10