LCOV - code coverage report
Current view: top level - sfx2/source/appl - macroloader.cxx (source / functions) Hit Total Coverage
Test: commit e02a6cb2c3e2b23b203b422e4e0680877f232636 Lines: 0 134 0.0 %
Date: 2014-04-14 Functions: 0 14 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 <macroloader.hxx>
      21             : 
      22             : #include <com/sun/star/document/UpdateDocMode.hpp>
      23             : #include <com/sun/star/document/MacroExecMode.hpp>
      24             : #include <com/sun/star/frame/DispatchResultState.hpp>
      25             : #include <basic/basmgr.hxx>
      26             : #include <basic/sbuno.hxx>
      27             : #include <cppuhelper/implbase5.hxx>
      28             : #include <cppuhelper/supportsservice.hxx>
      29             : #include <framework/documentundoguard.hxx>
      30             : #include <rtl/ref.hxx>
      31             : #include <sfx2/app.hxx>
      32             : #include <sfx2/docfile.hxx>
      33             : #include <sfx2/frame.hxx>
      34             : #include <sfx2/objsh.hxx>
      35             : #include <sfx2/request.hxx>
      36             : #include <sfx2/sfxsids.hrc>
      37             : #include <svl/intitem.hxx>
      38             : #include <tools/urlobj.hxx>
      39             : #include <vcl/svapp.hxx>
      40             : 
      41             : #include <boost/scoped_ptr.hpp>
      42             : 
      43             : using namespace ::com::sun::star;
      44             : using namespace ::com::sun::star::frame;
      45             : using namespace ::com::sun::star::lang;
      46             : using namespace ::com::sun::star::uno;
      47             : using namespace ::com::sun::star::util;
      48             : 
      49           0 : SfxMacroLoader::SfxMacroLoader(const css::uno::Sequence< css::uno::Any >& aArguments)
      50           0 :     throw (css::uno::Exception, css::uno::RuntimeException)
      51             : {
      52           0 :     Reference < XFrame > xFrame;
      53           0 :     if ( aArguments.getLength() )
      54             :     {
      55           0 :         aArguments[0] >>= xFrame;
      56           0 :         m_xFrame = xFrame;
      57           0 :     }
      58           0 : }
      59             : 
      60           0 : OUString SAL_CALL SfxMacroLoader::getImplementationName()
      61             :     throw (css::uno::RuntimeException, std::exception)
      62             : {
      63           0 :     return OUString("com.sun.star.comp.sfx2.SfxMacroLoader");
      64             : }
      65             : 
      66           0 : sal_Bool SAL_CALL SfxMacroLoader::supportsService(OUString const & ServiceName)
      67             :     throw (css::uno::RuntimeException, std::exception)
      68             : {
      69           0 :     return cppu::supportsService(this, ServiceName);
      70             : }
      71             : 
      72           0 : css::uno::Sequence<OUString> SAL_CALL SfxMacroLoader::getSupportedServiceNames()
      73             :     throw (css::uno::RuntimeException, std::exception)
      74             : {
      75           0 :     css::uno::Sequence< OUString > aSeq(1);
      76           0 :     aSeq[0] = OUString("com.sun.star.frame.ProtocolHandler");
      77           0 :     return aSeq;
      78             : }
      79             : 
      80           0 : SfxObjectShell* SfxMacroLoader::GetObjectShell_Impl()
      81             : {
      82           0 :     SfxObjectShell* pDocShell = NULL;
      83           0 :     Reference < XFrame > xFrame( m_xFrame.get(), UNO_QUERY );
      84           0 :     if ( xFrame.is() )
      85             :     {
      86           0 :         SfxFrame* pFrame=0;
      87           0 :         for ( pFrame = SfxFrame::GetFirst(); pFrame; pFrame = SfxFrame::GetNext( *pFrame ) )
      88             :         {
      89           0 :             if ( pFrame->GetFrameInterface() == xFrame )
      90           0 :                 break;
      91             :         }
      92             : 
      93           0 :         if ( pFrame )
      94           0 :             pDocShell = pFrame->GetCurrentDocument();
      95             :     }
      96             : 
      97           0 :     return pDocShell;
      98             : }
      99             : 
     100             : 
     101           0 : uno::Reference<frame::XDispatch> SAL_CALL SfxMacroLoader::queryDispatch(
     102             :     const util::URL&   aURL            ,
     103             :     const OUString&               /*sTargetFrameName*/,
     104             :     sal_Int32                            /*nSearchFlags*/    ) throw( uno::RuntimeException, std::exception )
     105             : {
     106           0 :     uno::Reference<frame::XDispatch> xDispatcher;
     107           0 :     if(aURL.Complete.startsWith("macro:"))
     108           0 :         xDispatcher = this;
     109           0 :     return xDispatcher;
     110             : }
     111             : 
     112             : 
     113             : uno::Sequence< uno::Reference<frame::XDispatch> > SAL_CALL
     114           0 :                 SfxMacroLoader::queryDispatches( const uno::Sequence < frame::DispatchDescriptor >& seqDescriptor )
     115             :                     throw( uno::RuntimeException, std::exception )
     116             : {
     117           0 :     sal_Int32 nCount = seqDescriptor.getLength();
     118           0 :     uno::Sequence< uno::Reference<frame::XDispatch> > lDispatcher(nCount);
     119           0 :     for( sal_Int32 i=0; i<nCount; ++i )
     120           0 :         lDispatcher[i] = this->queryDispatch( seqDescriptor[i].FeatureURL,
     121           0 :                                               seqDescriptor[i].FrameName,
     122           0 :                                               seqDescriptor[i].SearchFlags );
     123           0 :     return lDispatcher;
     124             : }
     125             : 
     126             : 
     127           0 : void SAL_CALL SfxMacroLoader::dispatchWithNotification(
     128             :     const util::URL& aURL, const uno::Sequence<beans::PropertyValue>& /*lArgs*/,
     129             :     const uno::Reference<frame::XDispatchResultListener>& xListener )
     130             :               throw (uno::RuntimeException, std::exception)
     131             : {
     132           0 :     SolarMutexGuard aGuard;
     133             : 
     134           0 :     uno::Any aAny;
     135           0 :     ErrCode nErr = loadMacro( aURL.Complete, aAny, GetObjectShell_Impl() );
     136           0 :     if( xListener.is() )
     137             :     {
     138             :         // always call dispatchFinished(), because we didn't load a document but
     139             :         // executed a macro instead!
     140           0 :         frame::DispatchResultEvent aEvent;
     141             : 
     142           0 :         aEvent.Source = static_cast< ::cppu::OWeakObject* >(this);
     143           0 :         if( nErr == ERRCODE_NONE )
     144           0 :             aEvent.State = frame::DispatchResultState::SUCCESS;
     145             :         else
     146           0 :             aEvent.State = frame::DispatchResultState::FAILURE;
     147             : 
     148           0 :         xListener->dispatchFinished( aEvent ) ;
     149           0 :     }
     150           0 : }
     151             : 
     152           0 : uno::Any SAL_CALL SfxMacroLoader::dispatchWithReturnValue(
     153             :     const util::URL& aURL, const uno::Sequence<beans::PropertyValue>& )
     154             :         throw (uno::RuntimeException, std::exception)
     155             : {
     156           0 :     uno::Any aRet;
     157           0 :     loadMacro( aURL.Complete, aRet, GetObjectShell_Impl() );
     158           0 :     return aRet;
     159             : }
     160             : 
     161           0 : void SAL_CALL SfxMacroLoader::dispatch(
     162             :     const util::URL& aURL, const uno::Sequence<beans::PropertyValue>& /*lArgs*/ )
     163             :         throw (uno::RuntimeException, std::exception)
     164             : {
     165           0 :     SolarMutexGuard aGuard;
     166             : 
     167           0 :     uno::Any aAny;
     168           0 :     loadMacro( aURL.Complete, aAny, GetObjectShell_Impl() );
     169           0 : }
     170             : 
     171           0 : void SAL_CALL SfxMacroLoader::addStatusListener(
     172             :     const uno::Reference< frame::XStatusListener >& ,
     173             :     const util::URL&                                                    )
     174             :               throw (uno::RuntimeException, std::exception)
     175             : {
     176             :     /* TODO
     177             :             How we can handle different listener for further coming or currently running dispatch() jobs
     178             :             without any inconsistency!
     179             :      */
     180           0 : }
     181             : 
     182             : 
     183           0 : void SAL_CALL SfxMacroLoader::removeStatusListener(
     184             :     const uno::Reference< frame::XStatusListener >&,
     185             :     const util::URL&                                                  )
     186             :         throw (uno::RuntimeException, std::exception)
     187             : {
     188           0 : }
     189             : 
     190           0 : ErrCode SfxMacroLoader::loadMacro( const OUString& rURL, com::sun::star::uno::Any& rRetval, SfxObjectShell* pSh )
     191             :     throw ( uno::RuntimeException )
     192             : {
     193             : #ifdef DISABLE_SCRIPTING
     194             :     (void) rURL;
     195             :     (void) rRetval;
     196             :     (void) pSh;
     197             :     return ERRCODE_BASIC_PROC_UNDEFINED;
     198             : #else
     199           0 :     SfxObjectShell* pCurrent = pSh;
     200           0 :     if ( !pCurrent )
     201             :         // all not full qualified names use the BASIC of the given or current document
     202           0 :         pCurrent = SfxObjectShell::Current();
     203             : 
     204             :     // 'macro:///lib.mod.proc(args)' => macro of App-BASIC
     205             :     // 'macro://[docname|.]/lib.mod.proc(args)' => macro of current or qualified document
     206             :     // 'macro://obj.method(args)' => direct API call, execute it via App-BASIC
     207           0 :     OUString aMacro( rURL );
     208           0 :     sal_Int32 nHashPos = aMacro.indexOf( '/', 8 );
     209           0 :     sal_Int32 nArgsPos = aMacro.indexOf( '(' );
     210           0 :     BasicManager *pAppMgr = SFX_APP()->GetBasicManager();
     211           0 :     BasicManager *pBasMgr = 0;
     212           0 :     ErrCode nErr = ERRCODE_NONE;
     213             : 
     214             :     // should a macro function be executed ( no direct API call)?
     215           0 :     if ( -1 != nHashPos && ( -1 == nArgsPos || nHashPos < nArgsPos ) )
     216             :     {
     217             :         // find BasicManager
     218           0 :         SfxObjectShell* pDoc = NULL;
     219           0 :         OUString aBasMgrName( INetURLObject::decode(aMacro.copy( 8, nHashPos-8 ), '%', INetURLObject::DECODE_WITH_CHARSET) );
     220           0 :         if ( aBasMgrName.isEmpty() )
     221           0 :             pBasMgr = pAppMgr;
     222           0 :         else if ( aBasMgrName == "." )
     223             :         {
     224             :             // current/actual document
     225           0 :             pDoc = pCurrent;
     226           0 :             if (pDoc)
     227           0 :                 pBasMgr = pDoc->GetBasicManager();
     228             :         }
     229             :         else
     230             :         {
     231             :             // full qualified name, find document by name
     232           0 :             for ( SfxObjectShell *pObjSh = SfxObjectShell::GetFirst();
     233           0 :                     pObjSh && !pBasMgr;
     234             :                     pObjSh = SfxObjectShell::GetNext(*pObjSh) )
     235           0 :                 if ( aBasMgrName == pObjSh->GetTitle(SFX_TITLE_APINAME) )
     236             :                 {
     237           0 :                     pDoc = pObjSh;
     238           0 :                     pBasMgr = pDoc->GetBasicManager();
     239             :                 }
     240             :         }
     241             : 
     242           0 :         if ( pBasMgr )
     243             :         {
     244           0 :             const bool bIsAppBasic = ( pBasMgr == pAppMgr );
     245           0 :             const bool bIsDocBasic = ( pBasMgr != pAppMgr );
     246             : 
     247           0 :             if ( pDoc )
     248             :             {
     249             :                 // security check for macros from document basic if an SFX doc is given
     250           0 :                 if ( !pDoc->AdjustMacroMode( OUString() ) )
     251             :                     // check forbids execution
     252           0 :                     return ERRCODE_IO_ACCESSDENIED;
     253             :             }
     254             : 
     255             :             // find BASIC method
     256           0 :             OUString aQualifiedMethod( INetURLObject::decode(aMacro.copy( nHashPos+1 ), '%', INetURLObject::DECODE_WITH_CHARSET) );
     257           0 :             OUString aArgs;
     258           0 :             if ( -1 != nArgsPos )
     259             :             {
     260             :                 // remove arguments from macro name
     261           0 :                 aArgs = aQualifiedMethod.copy( nArgsPos - nHashPos - 1 );
     262           0 :                 aQualifiedMethod = aQualifiedMethod.copy( 0, nArgsPos - nHashPos - 1 );
     263             :             }
     264             : 
     265           0 :             if ( pBasMgr->HasMacro( aQualifiedMethod ) )
     266             :             {
     267           0 :                 Any aOldThisComponent;
     268           0 :                 const bool bSetDocMacroMode = ( pDoc != NULL ) && bIsDocBasic;
     269           0 :                 const bool bSetGlobalThisComponent = ( pDoc != NULL ) && bIsAppBasic;
     270           0 :                 if ( bSetDocMacroMode )
     271             :                 {
     272             :                     // mark document: it executes an own macro, so it's in a modal mode
     273           0 :                     pDoc->SetMacroMode_Impl( true );
     274             :                 }
     275             : 
     276           0 :                 if ( bSetGlobalThisComponent )
     277             :                 {
     278             :                     // document is executed via AppBASIC, adjust ThisComponent variable
     279           0 :                     aOldThisComponent = pAppMgr->SetGlobalUNOConstant( "ThisComponent", makeAny( pDoc->GetModel() ) );
     280             :                 }
     281             : 
     282             :                 // just to let the shell be alive
     283           0 :                 SfxObjectShellRef xKeepDocAlive = pDoc;
     284             : 
     285             :                 {
     286             :                     // attempt to protect the document against the script tampering with its Undo Context
     287           0 :                     boost::scoped_ptr< ::framework::DocumentUndoGuard > pUndoGuard;
     288           0 :                     if ( bIsDocBasic )
     289           0 :                         pUndoGuard.reset( new ::framework::DocumentUndoGuard( pDoc->GetModel() ) );
     290             : 
     291             :                     // execute the method
     292           0 :                     SbxVariableRef retValRef = new SbxVariable;
     293           0 :                     nErr = pBasMgr->ExecuteMacro( aQualifiedMethod, aArgs, retValRef );
     294           0 :                     if ( nErr == ERRCODE_NONE )
     295           0 :                         rRetval = sbxToUnoValue( retValRef );
     296             :                 }
     297             : 
     298           0 :                 if ( bSetGlobalThisComponent )
     299             :                 {
     300           0 :                     pAppMgr->SetGlobalUNOConstant( "ThisComponent", aOldThisComponent );
     301             :                 }
     302             : 
     303           0 :                 if ( bSetDocMacroMode )
     304             :                 {
     305             :                     // remove flag for modal mode
     306           0 :                     pDoc->SetMacroMode_Impl( false );
     307           0 :                 }
     308             :             }
     309             :             else
     310           0 :                 nErr = ERRCODE_BASIC_PROC_UNDEFINED;
     311             :         }
     312             :         else
     313           0 :             nErr = ERRCODE_IO_NOTEXISTS;
     314             :     }
     315             :     else
     316             :     {
     317             :         // direct API call on a specified object
     318           0 :         OUStringBuffer aCall;
     319           0 :         aCall.append('[').append(INetURLObject::decode(aMacro.copy(6), '%',
     320           0 :             INetURLObject::DECODE_WITH_CHARSET));
     321           0 :         aCall.append(']');
     322           0 :         pAppMgr->GetLib(0)->Execute(aCall.makeStringAndClear());
     323           0 :         nErr = SbxBase::GetError();
     324             :     }
     325             : 
     326           0 :     SbxBase::ResetError();
     327           0 :     return nErr;
     328             : #endif
     329             : }
     330             : 
     331             : extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface * SAL_CALL
     332           0 : com_sun_star_comp_sfx2_SfxMacroLoader_get_implementation(
     333             :     css::uno::XComponentContext *,
     334             :     css::uno::Sequence<css::uno::Any> const &arguments)
     335             : {
     336           0 :     return cppu::acquire(new SfxMacroLoader(arguments));
     337             : }
     338             : 
     339             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10