summaryrefslogtreecommitdiff
path: root/sfx2/source/control/macrconf.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'sfx2/source/control/macrconf.cxx')
-rw-r--r--sfx2/source/control/macrconf.cxx874
1 files changed, 874 insertions, 0 deletions
diff --git a/sfx2/source/control/macrconf.cxx b/sfx2/source/control/macrconf.cxx
new file mode 100644
index 000000000000..9e8657ae0c82
--- /dev/null
+++ b/sfx2/source/control/macrconf.cxx
@@ -0,0 +1,874 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sfx2.hxx"
+#include <basic/sbstar.hxx>
+#include <basic/basmgr.hxx>
+#ifndef _SBX_HXX //autogen
+#include <basic/sbx.hxx>
+#endif
+#include <svl/intitem.hxx>
+#include <basic/sbmeth.hxx>
+#include <basic/sbmod.hxx>
+#ifndef _BASIC_SBUNO_HXX
+#include <basic/sbuno.hxx>
+#endif
+
+#include <osl/mutex.hxx>
+
+#include <com/sun/star/script/XEngine.hpp>
+#include <com/sun/star/document/MacroExecMode.hpp>
+
+#ifndef GCC
+#endif
+
+#ifndef _UNOTOOLS_PROCESSFACTORY_HXX
+#include <comphelper/processfactory.hxx>
+#endif
+#include <unotools/intlwrapper.hxx>
+
+#include <sfx2/msgpool.hxx>
+#include <sfx2/macrconf.hxx>
+#include "sfxbasic.hxx"
+#include <sfx2/sfx.hrc>
+#include <sfx2/app.hxx>
+#include <sfx2/objsh.hxx>
+#include <sfx2/dispatch.hxx>
+#include "minfitem.hxx"
+#include "imgmgr.hxx"
+#include <sfx2/evntconf.hxx>
+#include <sfx2/docfile.hxx>
+#include <sfx2/genlink.hxx>
+#include <sfx2/viewfrm.hxx>
+#include <appdata.hxx>
+#include "objshimp.hxx"
+#include <sfx2/request.hxx>
+
+static const sal_uInt16 nCompatVersion = 2;
+static const sal_uInt16 nVersion = 3;
+
+// Static member
+SfxMacroConfig* SfxMacroConfig::pMacroConfig = NULL;
+
+SfxMacroConfig* SfxMacroConfig::GetOrCreate()
+{
+ ::osl::MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() );
+ if ( !pMacroConfig )
+ pMacroConfig = new SfxMacroConfig;
+ return pMacroConfig;
+}
+
+void SfxMacroConfig::Release_Impl()
+{
+ ::osl::MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() );
+ DELETEZ( pMacroConfig );
+}
+
+//==========================================================================
+
+struct SfxMacroConfig_Impl
+{
+ SfxMacroInfoArr_Impl aArr;
+ sal_uInt32 nEventId;
+ sal_Bool bWaitingForCallback;
+
+ SfxMacroConfig_Impl()
+ : nEventId( 0 )
+ , bWaitingForCallback( sal_False )
+ {}
+};
+
+//==========================================================================
+
+SbMethod* SfxQueryMacro_Impl( BasicManager* pMgr , const String& rMacro,
+ const String &rLibName, const String& rModule )
+{
+ IntlWrapper aIntlWrapper( ::comphelper::getProcessServiceFactory(), Application::GetSettings().GetLocale() );
+ const CollatorWrapper* pCollator = aIntlWrapper.getCollator();
+ sal_uInt16 nLibCount = pMgr->GetLibCount();
+ for ( sal_uInt16 nLib = 0; nLib < nLibCount; ++nLib )
+ {
+ if ( COMPARE_EQUAL == pCollator->compareString( pMgr->GetLibName( nLib ), rLibName ) )
+ {
+ StarBASIC* pLib = pMgr->GetLib( nLib );
+ if( !pLib )
+ {
+ pMgr->LoadLib( nLib );
+ pLib = pMgr->GetLib( nLib );
+ }
+
+ if( pLib )
+ {
+ sal_uInt16 nModCount = pLib->GetModules()->Count();
+ for( sal_uInt16 nMod = 0; nMod < nModCount; ++nMod )
+ {
+ SbModule* pMod = (SbModule*)pLib->GetModules()->Get( nMod );
+ if ( pMod && COMPARE_EQUAL == pCollator->compareString( pMod->GetName(), rModule ) )
+ {
+ SbMethod* pMethod = (SbMethod*)pMod->Find( rMacro, SbxCLASS_METHOD );
+ if( pMethod )
+ return pMethod;
+ }
+ }
+ }
+ }
+ }
+ return 0;
+}
+
+SbMethod* SfxQueryMacro( BasicManager* pMgr , const String& rMacro )
+{
+ sal_uInt16 nLast = 0;
+ String aMacro = rMacro;
+ String aLibName = aMacro.GetToken( 0, '.', nLast );
+ String aModule = aMacro.GetToken( 0, '.', nLast );
+ aMacro.Erase( 0, nLast );
+
+ return SfxQueryMacro_Impl( pMgr, aMacro, aLibName, aModule );
+}
+
+ErrCode SfxCallMacro( BasicManager* pMgr, const String& rCode,
+ SbxArray *pArgs, SbxValue *pRet )
+{
+ ErrCode nErr;
+ SfxApplication *pApp = SFX_APP();
+ pApp->EnterBasicCall();
+ SbMethod* pMethod = SfxQueryMacro( pMgr, rCode );
+ if ( pMethod )
+ {
+ if ( pArgs )
+ pMethod->SetParameters( pArgs );
+ nErr = pMethod->Call( pRet );
+ }
+ else
+ nErr = ERRCODE_BASIC_PROC_UNDEFINED;
+
+ pApp->LeaveBasicCall();
+ return nErr;
+}
+
+//==========================================================================
+
+SfxMacroInfo::SfxMacroInfo( const String& rURL ) :
+ pHelpText(0),
+ nRefCnt(0),
+ bAppBasic(TRUE),
+ nSlotId(0),
+ pSlot(0)
+{
+ if ( rURL.CompareToAscii( "macro:", 6 ) == COMPARE_EQUAL )
+ {
+ String aTmp = rURL.Copy( 6 );
+ if ( aTmp.GetTokenCount('/') > 3 )
+ {
+ // 'macro:///lib.mod.proc(args)' => Macro via App-BASIC-Mgr
+ // 'macro://[docname|.]/lib.mod.proc(args)' => Macro via zugehoerigen Doc-BASIC-Mgr
+ if ( aTmp.CompareToAscii("///", 3 ) != COMPARE_EQUAL )
+ bAppBasic = FALSE;
+ aTmp = rURL.GetToken( 3, '/' );
+ if ( aTmp.GetTokenCount('.') == 3 )
+ {
+ aLibName = aTmp.GetToken( 0, '.' );
+ aModuleName = aTmp.GetToken( 1, '.' );
+ aMethodName = aTmp.GetToken( 2, '.' );
+
+ // Remove arguments to be compatible
+ aMethodName.SearchAndReplaceAscii( "()", String(), sal::static_int_cast< xub_StrLen >(std::max( aMethodName.Len()-2, 0 )));
+ }
+ }
+
+ DBG_ASSERT( aLibName.Len() && aModuleName.Len() && aMethodName.Len(), "Wrong macro URL!" );
+ }
+ else
+ aMethodName = rURL;
+}
+
+SfxMacroInfo::SfxMacroInfo( bool _bAppBasic ) :
+ pHelpText(0),
+ nRefCnt(0),
+ bAppBasic(_bAppBasic),
+ nSlotId(0),
+ pSlot(0)
+{}
+
+//==========================================================================
+
+SfxMacroInfo::SfxMacroInfo(bool _bAppBasic, const String& rLibName,
+ const String& rModuleName, const String& rMethodName) :
+ pHelpText(0),
+ nRefCnt(0),
+ bAppBasic(_bAppBasic),
+ aLibName(rLibName),
+ aModuleName(rModuleName),
+ aMethodName(rMethodName),
+ nSlotId(0),
+ pSlot(0)
+{
+}
+
+//==========================================================================
+
+SfxMacroInfo::SfxMacroInfo(bool _bAppBasic, const String& rQualifiedName )
+: pHelpText(0),
+ nRefCnt(0),
+ bAppBasic(_bAppBasic),
+ nSlotId(0),
+ pSlot(0)
+{
+ sal_uInt16 nCount = rQualifiedName.GetTokenCount('.');
+ aMethodName = rQualifiedName.GetToken( nCount-1, '.' );
+ if ( nCount > 1 )
+ aModuleName = rQualifiedName.GetToken( nCount-2, '.' );
+ if ( nCount > 2 )
+ aLibName = rQualifiedName.GetToken( 0, '.' );
+}
+
+//==========================================================================
+
+SfxMacroInfo::SfxMacroInfo(SfxMacroInfo& rOther) :
+ pHelpText(0),
+ nRefCnt(0),
+ bAppBasic(rOther.bAppBasic),
+ aLibName(rOther.aLibName),
+ aModuleName(rOther.aModuleName),
+ aMethodName(rOther.aMethodName),
+ nSlotId(rOther.nSlotId),
+ pSlot(0)
+{}
+
+//==========================================================================
+
+SfxMacroInfo::~SfxMacroInfo()
+{
+ delete pSlot;
+ delete pHelpText;
+}
+
+//==========================================================================
+
+sal_Bool SfxMacroInfo::operator==(const SfxMacroInfo& rOther) const
+{
+ if ( GetQualifiedName() == rOther.GetQualifiedName() &&
+ bAppBasic == rOther.bAppBasic )
+ return sal_True;
+ else
+ return sal_False;
+}
+
+//==========================================================================
+
+String SfxMacroInfo::GetMacroName() const
+{
+ String aMacroName = aMethodName;
+ aMacroName += '(';
+ aMacroName += aLibName;
+ aMacroName += '.';
+ aMacroName += aModuleName;
+ aMacroName += ')';
+ return aMacroName;
+}
+
+//==========================================================================
+
+String SfxMacroInfo::GetQualifiedName() const
+{
+ String aMacroName;
+ if( aMacroName.Len() || aLibName.Len() )
+ {
+ // Altes Format
+ aMacroName = aLibName;
+ aMacroName += '.';
+ aMacroName += aModuleName;
+ aMacroName += '.';
+ }
+
+ // Wg. ::com::sun::star::script::JavaScript kein Zerlegen des Strings mehr
+ aMacroName += aMethodName;
+ return aMacroName;
+}
+
+String SfxMacroInfo::GetFullQualifiedName() const
+{
+ // Liefert nur Unsinn, wenn f"ur ein ::com::sun::star::script::JavaScript aufgerufen !
+ String aRet;
+ if ( bAppBasic )
+ aRet = SFX_APP()->GetName();
+ aRet += '.';
+ aRet += GetQualifiedName();
+ return aRet;
+}
+
+String SfxMacroInfo::GetURL() const
+{
+ if ( !aLibName.Len() )
+ return aMethodName;
+
+ // 'macro:///lib.mod.proc(args)' => Macro via App-BASIC-Mgr
+ // 'macro://[docname|.]/lib.mod.proc(args)' => Macro via zugehoerigen Doc-BASIC-Mgr
+ // 'macro://obj.method(args)' => Object via App-BASIC-Mgr
+ String aURL( String::CreateFromAscii("macro://") );
+ if ( !bAppBasic )
+ aURL += '.';
+ aURL += '/';
+ aURL += aLibName;
+ aURL += '.';
+ aURL += aModuleName;
+ aURL += '.';
+ aURL += aMethodName;
+ aURL += String::CreateFromAscii("()");
+
+ return aURL;
+}
+
+//==========================================================================
+
+BasicManager* SfxMacroInfo::GetBasicManager() const
+{
+ if (bAppBasic)
+ {
+ return SFX_APP()->GetBasicManager();
+ }
+ else
+ {
+ SfxObjectShell *pCurrDocShell = SfxObjectShell::Current();
+ return pCurrDocShell ? pCurrDocShell->GetBasicManager() :
+ SFX_APP()->GetBasicManager();
+ }
+}
+
+//==========================================================================
+
+String SfxMacroInfo::GetBasicName() const
+{
+ if (bAppBasic)
+ {
+ return SFX_APP()->GetName();
+ }
+ else
+ {
+ SfxObjectShell *pCurrDocShell = SfxObjectShell::Current();
+ if ( pCurrDocShell )
+ return pCurrDocShell->GetTitle();
+ else
+ return SFX_APP()->GetName();
+ }
+}
+
+String SfxMacroInfo::GetHelpText() const
+{
+ if ( pHelpText )
+ return *pHelpText;
+ return String();
+}
+
+String SfxMacroConfig::RequestHelp( sal_uInt16 nId )
+{
+ SfxMacroInfo *pInfo = SFX_APP()->GetMacroConfig()->GetMacroInfo( nId );
+ if ( !pInfo )
+ return String();
+
+ if ( !pInfo->pHelpText )
+ {
+ SbMethod *pMethod =
+ SfxQueryMacro_Impl( pInfo->GetBasicManager(), pInfo->aMethodName,
+ pInfo->aLibName, pInfo->aModuleName );
+ if ( pMethod && pMethod->GetInfo() )
+ pInfo->pHelpText = new String( pMethod->GetInfo()->GetComment() );
+ }
+
+ return pInfo->GetHelpText();
+}
+
+void SfxMacroInfo::SetHelpText( const String& rName )
+{
+ if ( !pHelpText )
+ pHelpText = new String;
+ *pHelpText = rName;
+}
+
+//==========================================================================
+
+SvStream& operator >> (SvStream& rStream, SfxMacroInfo& rInfo)
+{
+ sal_uInt16 nAppBasic, nFileVersion;
+ String aDocName;
+
+ rStream >> nFileVersion;
+ if ( nVersion < nCompatVersion )
+ {
+ // In der 1.Version ohne Versionskennung
+ nAppBasic = nVersion;
+ nFileVersion = 1;
+ rStream.ReadByteString(aDocName,RTL_TEXTENCODING_UTF8);
+ rStream.ReadByteString(rInfo.aLibName,RTL_TEXTENCODING_UTF8);
+ rStream.ReadByteString(rInfo.aModuleName,RTL_TEXTENCODING_UTF8);
+ rStream.ReadByteString(rInfo.aMethodName,RTL_TEXTENCODING_UTF8);
+ }
+ else
+ {
+ String aInput;
+ rStream >> nAppBasic;
+ rStream.ReadByteString(aDocName,RTL_TEXTENCODING_UTF8); // Vorsicht: kann bei AppName Unsinn sein!
+ rStream.ReadByteString(rInfo.aLibName,RTL_TEXTENCODING_UTF8);
+ rStream.ReadByteString(rInfo.aModuleName,RTL_TEXTENCODING_UTF8);
+ rStream.ReadByteString(aInput,RTL_TEXTENCODING_UTF8);
+
+ if ( nFileVersion == nCompatVersion )
+ rInfo.aMethodName = aInput;
+ else
+ {
+ sal_uInt16 nCount = aInput.GetTokenCount('.');
+ rInfo.aMethodName = aInput.GetToken( nCount-1, '.' );
+ if ( nCount > 1 )
+ rInfo.aModuleName = aInput.GetToken( nCount-2, '.' );
+ if ( nCount > 2 )
+ rInfo.aLibName = aInput.GetToken( 0, '.' );
+ }
+ }
+
+ rInfo.bAppBasic = (sal_Bool) nAppBasic;
+ return rStream;
+}
+
+int SfxMacroInfo::Load( SvStream& rStream )
+{
+ rStream >> (*this);
+ nSlotId = SFX_APP()->GetMacroConfig()->GetSlotId(this);
+ return 0;
+}
+
+//==========================================================================
+
+SvStream& operator << (SvStream& rStream, const SfxMacroInfo& rInfo)
+{
+ if ( rInfo.bAppBasic )
+ {
+ rStream << nVersion
+ << (sal_uInt16) rInfo.bAppBasic;
+ rStream.WriteByteString(rInfo.GetBasicName(),RTL_TEXTENCODING_UTF8);
+ rStream.WriteByteString(rInfo.aLibName,RTL_TEXTENCODING_UTF8);
+ rStream.WriteByteString(rInfo.aModuleName,RTL_TEXTENCODING_UTF8);
+ rStream.WriteByteString(rInfo.aMethodName,RTL_TEXTENCODING_UTF8);
+ }
+ else
+ {
+ rStream << nVersion
+ << (sal_uInt16) rInfo.bAppBasic;
+ rStream.WriteByteString(SFX_APP()->GetName(),RTL_TEXTENCODING_UTF8);
+ rStream.WriteByteString(rInfo.aLibName,RTL_TEXTENCODING_UTF8);
+ rStream.WriteByteString(rInfo.aModuleName,RTL_TEXTENCODING_UTF8);
+ rStream.WriteByteString(rInfo.aMethodName,RTL_TEXTENCODING_UTF8);
+ }
+
+ return rStream;
+}
+
+sal_Bool SfxMacroInfo::Compare( const SvxMacro& rMacro ) const
+{
+ String aName = rMacro.GetLibName();
+ aName += '.';
+ aName += rMacro.GetMacName();
+ if ( GetFullQualifiedName() == aName )
+ return sal_True;
+ return sal_False;
+}
+
+//==========================================================================
+
+SfxMacroConfig::SfxMacroConfig()
+{
+ pImp = new SfxMacroConfig_Impl;
+}
+
+//==========================================================================
+
+SfxMacroConfig::~SfxMacroConfig()
+{
+ if ( pImp->nEventId )
+ Application::RemoveUserEvent( pImp->nEventId );
+ delete pImp;
+}
+
+//==========================================================================
+
+SFX_STATE_STUB( SfxApplication, MacroState_Impl )
+SFX_EXEC_STUB( SfxApplication, MacroExec_Impl )
+
+sal_uInt16 SfxMacroConfig::GetSlotId(SfxMacroInfoPtr pInfo)
+{
+ sal_uInt16 nCount = pImp->aArr.Count(); // Macro suchen
+ sal_uInt16 i;
+ for (i=0; i<nCount; i++)
+ if ((*(pImp->aArr)[i]) == (*pInfo))
+ break;
+
+ if (i == nCount)
+ { // Macro noch unbekannt
+ nCount = aIdArray.Count();
+ sal_uInt16 n;
+ for (n=0; n<nCount; n++) // freie SlotId suchen
+ if (aIdArray[n] > SID_MACRO_START + n)
+ break;
+
+ sal_uInt16 nNewSlotId = SID_MACRO_START + n;
+ if ( nNewSlotId > SID_MACRO_END )
+ return 0;
+ aIdArray.Insert( SID_MACRO_START + n, n );
+
+ SfxSlot *pNewSlot = new SfxSlot;
+ pNewSlot->nSlotId = SID_MACRO_START + n;
+ pNewSlot->nGroupId = 0;
+ pNewSlot->nFlags = SFX_SLOT_ASYNCHRON;
+ pNewSlot->nMasterSlotId = 0;
+ pNewSlot->nValue = 0;
+ pNewSlot->fnExec = SFX_STUB_PTR(SfxApplication,MacroExec_Impl);
+ pNewSlot->fnState = SFX_STUB_PTR(SfxApplication,MacroState_Impl);
+ pNewSlot->pType = 0; HACK(SFX_TYPE(SfxVoidItem))
+ pNewSlot->pName = pNewSlot->pMethodName = U2S(pInfo->aMethodName).getStr();
+ pNewSlot->pLinkedSlot = 0;
+ pNewSlot->nArgDefCount = 0;
+ pNewSlot->pFirstArgDef = 0;
+ pNewSlot->pUnoName = 0;
+
+ if (nCount)
+ {
+ SfxSlot *pSlot = (pImp->aArr)[0]->pSlot;
+ pNewSlot->pNextSlot = pSlot->pNextSlot;
+ pSlot->pNextSlot = pNewSlot;
+ }
+ else
+ pNewSlot->pNextSlot = pNewSlot;
+
+ // Macro uebernehmen
+ SfxMacroInfoPtr pNewInfo = new SfxMacroInfo(*pInfo);
+ pNewInfo->nSlotId = SID_MACRO_START + n;
+ pImp->aArr.Insert(pNewInfo,n);
+ pNewInfo->pSlot = pNewSlot;
+ pInfo->nSlotId = pNewInfo->nSlotId;
+ pNewInfo->nRefCnt++;
+ }
+ else
+ {
+ pInfo->nSlotId = (pImp->aArr)[i]->nSlotId;
+ (pImp->aArr)[i]->nRefCnt++;
+ }
+
+ return pInfo->nSlotId;
+}
+
+//==========================================================================
+
+void SfxMacroConfig::ReleaseSlotId(sal_uInt16 nId)
+{
+ DBG_ASSERT( IsMacroSlot( nId ), "SlotId ist kein Macro!");
+
+ sal_uInt16 nCount = pImp->aArr.Count();
+ for (sal_uInt16 i=0; i<nCount; i++)
+ {
+ SfxMacroInfo *pInfo = (pImp->aArr)[i];
+ if (pInfo->nSlotId == nId)
+ {
+ pInfo->nRefCnt--;
+ if (pInfo->nRefCnt == 0)
+ {
+ // Slot wird nicht mehr referenziert, also holen
+ SfxSlot *pSlot = pInfo->pSlot;
+
+ // Slot aus der Verkettung rausnehmen
+ while (pSlot->pNextSlot != pInfo->pSlot)
+ pSlot = (SfxSlot*) pSlot->pNextSlot;
+ pSlot->pNextSlot = pInfo->pSlot->pNextSlot;
+
+ // Slot selbst kurz schlie\sen
+ pSlot = pInfo->pSlot;
+ pSlot->pNextSlot = pSlot;
+
+ // MacroInfo aus Array entfernen, damit sie kein Unheil
+ // anrichten kann
+ pImp->aArr.Remove(i);
+
+ // SlotId wieder freigeben
+ sal_uInt16 nIdCount = aIdArray.Count();
+ for (sal_uInt16 n=0; n<nIdCount; n++)
+ {
+ if (aIdArray[n] == nId)
+ {
+ aIdArray.Remove(n);
+ break;
+ }
+ }
+
+ // Sofern nicht die Applikation heruntergefahren wird, mu\s
+ // der Slot asynchron gel"oscht werden, falls er in seinem
+ // eigenen Execute abgeschossen wird!
+ if ( !SFX_APP()->Get_Impl()->bInQuit )
+ pImp->nEventId = Application::PostUserEvent( LINK(this, SfxMacroConfig, EventHdl_Impl), pInfo );
+ else
+ EventHdl_Impl( pInfo );
+ }
+ return;
+ }
+ }
+
+ DBG_ERROR("Macro-SlotId nicht gefunden!");
+}
+
+//==========================================================================
+
+void SfxMacroConfig::RegisterSlotId(sal_uInt16 nId)
+{
+ DBG_ASSERT( IsMacroSlot( nId ), "SlotId ist kein Macro!");
+
+ sal_uInt16 nCount = pImp->aArr.Count();
+ for (sal_uInt16 i=0; i<nCount; i++)
+ {
+ if ((pImp->aArr)[i]->nSlotId == nId)
+ {
+ (pImp->aArr)[i]->nRefCnt++;
+ return;
+ }
+ }
+
+ DBG_ERROR("Macro-SlotId nicht gefunden!");
+}
+
+//==========================================================================
+
+SfxMacroInfo* SfxMacroConfig::GetMacroInfo(sal_uInt16 nId) const
+{
+ sal_uInt16 nCount = pImp->aArr.Count();
+ for (sal_uInt16 i=0; i<nCount; i++)
+ if ((pImp->aArr)[i]->nSlotId == nId)
+ return (pImp->aArr)[i];
+
+ return 0;
+}
+
+//==========================================================================
+
+const SfxMacroInfo* SfxMacroConfig::GetMacroInfo_Impl( const SvxMacro *pMacro ) const
+{
+ sal_uInt16 nCount = pImp->aArr.Count();
+ for (sal_uInt16 i=0; i<nCount; i++)
+ if ((pImp->aArr)[i]->Compare(*pMacro) )
+ return (pImp->aArr)[i];
+ return 0;
+}
+
+//==========================================================================
+
+sal_Bool SfxMacroConfig::ExecuteMacro( sal_uInt16 nId, const String& rArgs ) const
+{
+ const SfxMacroInfo* pInfo = GetMacroInfo( nId );
+ if ( !pInfo )
+ return sal_False;
+
+ SfxObjectShell* pSh = SfxObjectShell::Current();
+
+ SvxMacro aMacro( pInfo->GetQualifiedName(), pInfo->GetBasicName(), STARBASIC );
+ sal_Bool bRet = ExecuteMacro( pSh, &aMacro, rArgs );
+
+ // Release, da im Dispatcher-Execute ein Register gemacht wurde
+ ((SfxMacroConfig*)this)->ReleaseSlotId( nId );
+ return bRet;
+}
+
+sal_Bool SfxMacroConfig::ExecuteMacro( SfxObjectShell *pSh, const SvxMacro* pMacro, const String& /*rArgs*/ ) const
+{
+ SfxApplication *pApp = SFX_APP();
+
+ // Name des Macros oder Scripts bzw. ScriptCode
+ String aCode( pMacro->GetMacName() );
+ ErrCode nErr = ERRCODE_NONE;
+
+ // Ist es ein Basic-Macro ?
+ ScriptType eSType = pMacro->GetScriptType();
+ sal_Bool bIsBasic = eSType == STARBASIC;
+ sal_Bool bIsStarScript = ( eSType == EXTENDED_STYPE && pMacro->GetLibName().SearchAscii( "StarScript" ) != STRING_NOTFOUND );
+ sal_Bool bIsBasicLibBased = bIsBasic || bIsStarScript || !pSh;
+
+ if ( bIsBasicLibBased )
+ {
+ pApp->EnterBasicCall();
+ BasicManager *pAppMgr = SFX_APP()->GetBasicManager();
+ if( bIsBasic )
+ {
+ // BasicManager von Document?
+ BasicManager *pMgr = pSh ? pSh->GetBasicManager() : NULL;
+
+ // Da leider der Name zwischendurch h"aufig gewechselt hat ...
+ if( SFX_APP()->GetName() == pMacro->GetLibName() ||
+ pMacro->GetLibName().EqualsAscii("StarDesktop") )
+ pMgr = pAppMgr;
+ else if ( pMgr == pAppMgr )
+ pMgr = NULL;
+
+ if ( pSh && pMgr && pMgr != pAppMgr )
+ {
+ if ( !pSh->AdjustMacroMode( String() ) )
+ return sal_False;
+ }
+
+ if ( pSh && pMgr && pMgr == pAppMgr )
+ {
+ ::com::sun::star::uno::Any aOldThisComponent = pAppMgr->SetGlobalUNOConstant( "ThisComponent", makeAny( pSh->GetModel() ) );
+ nErr = Call( 0, aCode, pMgr );
+ pAppMgr->SetGlobalUNOConstant( "ThisComponent", aOldThisComponent );
+ }
+ else if ( pMgr )
+ nErr = Call( 0, aCode, pMgr );
+ else
+ nErr = SbxERR_NO_METHOD;
+
+ }
+
+ pApp->LeaveBasicCall();
+ }
+ else
+ {
+ nErr = SbxERR_NO_METHOD;
+ }
+
+ return ( nErr == ERRCODE_NONE );
+}
+
+sal_Bool SfxMacroConfig::CheckMacro( SfxObjectShell *pSh, const SvxMacro* pMacro ) const
+{
+ SfxApplication *pApp = SFX_APP();
+
+ // Name des Macros oder Scripts bzw. ScriptCode
+ String aCode( pMacro->GetMacName() );
+ ErrCode nErr = ERRCODE_NONE;
+
+ // BasicManager von Document oder Application
+ pApp->EnterBasicCall();
+ BasicManager *pAppMgr = SFX_APP()->GetBasicManager();
+ BasicManager *pMgr = pSh ? pSh->GetBasicManager() : NULL;
+
+ // Da leider der Name zwischendurch h"aufig gewechselt hat ...
+ if( SFX_APP()->GetName() == pMacro->GetLibName() ||
+ pMacro->GetLibName().EqualsAscii("StarDesktop") )
+ pMgr = pAppMgr;
+ else if ( pMgr == pAppMgr )
+ pMgr = NULL;
+
+ if ( !pMgr || !SfxQueryMacro( pMgr, aCode ) )
+ nErr = SbxERR_NO_METHOD;
+ pApp->LeaveBasicCall();
+ return ( nErr == ERRCODE_NONE );
+}
+
+//==========================================================================
+
+sal_Bool SfxMacroConfig::CheckMacro( sal_uInt16 nId ) const
+{
+ const SfxMacroInfo* pInfo = GetMacroInfo( nId );
+ if ( !pInfo )
+ return sal_False;
+
+ // Basic nur initialisieren, wenn default nicht ::com::sun::star::script::JavaScript; dann mu\s
+ // in IsBasic() sowieso das Basic angelegt werden
+ SfxObjectShell* pSh = SfxObjectShell::Current();
+
+ SfxApplication *pApp = SFX_APP();
+ pApp->EnterBasicCall();
+
+ // BasicManager von Document oder Application
+ BasicManager *pAppMgr = SFX_APP()->GetBasicManager();
+ BasicManager *pMgr = pSh ? pSh->GetBasicManager() : NULL;
+
+ if( SFX_APP()->GetName() == pInfo->GetBasicName() )
+ pMgr = SFX_APP()->GetBasicManager();
+ else if ( pMgr == pAppMgr )
+ pMgr = NULL;
+
+ String aFull( pInfo->GetQualifiedName() );
+ sal_Bool bIsBasic = pMgr ? IsBasic( 0, aFull, pMgr ) : sal_False;
+ pApp->LeaveBasicCall();
+ return bIsBasic;
+}
+
+//==========================================================================
+
+IMPL_LINK( SfxMacroConfig, CallbackHdl_Impl, SfxMacroConfig*, pConfig )
+{
+ (void)pConfig; // unused
+ pImp->bWaitingForCallback = sal_False;
+ return 0;
+}
+
+IMPL_LINK( SfxMacroConfig, EventHdl_Impl, SfxMacroInfo*, pInfo )
+{
+ delete pInfo;
+ pImp->nEventId = 0;
+ return 0;
+}
+
+sal_Bool SfxMacroConfig::IsBasic(
+ SbxObject* /*pVCtrl*/,
+ const String& rCode,
+ BasicManager* pMgr )
+{
+ sal_Bool bFound;
+ SFX_APP()->EnterBasicCall();
+ bFound = SfxQueryMacro( pMgr, rCode ) != 0;
+ SFX_APP()->LeaveBasicCall();
+ return bFound;
+}
+
+ErrCode SfxMacroConfig::Call(
+ SbxObject* /*pVCtrl*/,
+ const String& rCode,
+ BasicManager* pMgr,
+ SbxArray *pArgs,
+ SbxValue *pRet )
+{
+ SfxApplication *pApp = SFX_APP();
+ pApp->EnterBasicCall();
+ SbMethod* pMethod = SfxQueryMacro( pMgr, rCode );
+ ErrCode nErr = 0;
+ if( pMethod )
+ {
+ if ( pArgs )
+ pMethod->SetParameters( pArgs );
+ nErr = pMethod->Call( pRet );
+ }
+ else
+ nErr = ERRCODE_BASIC_PROC_UNDEFINED;
+
+ pApp->LeaveBasicCall();
+ return nErr;
+}
+
+
+sal_Bool SfxMacroConfig::IsMacroSlot( sal_uInt16 nId )
+{
+ return ( nId >= SID_MACRO_START && nId <= SID_MACRO_END );
+}
+
+