/************************************************************** * * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. * *************************************************************/ // MARKER(update_precomp.py): autogen include statement, do not remove #include "precompiled_sfx2.hxx" #include #include #ifndef GCC #endif // wg. pSlotPool #include "appdata.hxx" #include #include #include #include #include #include "sfxtypes.hxx" #include "sfx2/sfxresid.hxx" #include "arrdecl.hxx" #include #include //==================================================================== struct SfxSIDRegistration_Impl { String _aGroup; String _aName; sal_uInt16 _nSID; }; struct SfxSlotType_Impl { sal_uInt16 nId; TypeId nType; SfxSlotType_Impl( sal_uInt16 nTheId, TypeId nTheType ): nId(nTheId), nType(nTheType) {} }; DECL_2BYTEARRAY(SfxSlotGroupArr_Impl, sal_uInt16, 6, 4) DECL_PTRARRAY(SfxInterfaceArr_Impl, SfxInterface*, 6, 3) DECL_PTRARRAY(SfxSlotTypeArr_Impl, SfxSlotType_Impl*, 8, 8) //==================================================================== SfxSlotPool::SfxSlotPool( SfxSlotPool *pParent, ResMgr* pResManager ) : _pGroups(0) , _pTypes(0) , _pParentPool( pParent ) , _pResMgr( pResManager ) , _pInterfaces(0) , _nCurGroup(0) , _nCurInterface(0) , _nCurMsg(0) , _pUnoSlots( 0 ) { if ( !_pResMgr ) _pResMgr = SfxApplication::GetOrCreate()->GetOffResManager_Impl(); } //==================================================================== SfxSlotPool::~SfxSlotPool() { _pParentPool = 0; for ( SfxInterface *pIF = FirstInterface(); pIF; pIF = FirstInterface() ) delete pIF; delete _pInterfaces; delete _pGroups; if ( _pTypes ) { for ( sal_uInt16 n =_pTypes->Count(); n--; ) delete _pTypes->GetObject(n); delete _pTypes; } } //==================================================================== // registers the availability of the Interface of functions void SfxSlotPool::RegisterInterface( SfxInterface& rInterface ) { DBG_MEMTEST(); // add to the list of SfxObjectInterface instances if ( _pInterfaces == 0 ) _pInterfaces = new SfxInterfaceArr_Impl; _pInterfaces->Append(&rInterface); // bei einem (einzelnen) Null-Slot abbrechen (aus syntaktischen Gr"unden // enthalten interfaces immer mindestens einen Slot) if ( rInterface.Count() == 1 && !rInterface[0]->nSlotId ) return; // possibly add Interface-id and group-ids of funcs to the list of groups if ( !_pGroups ) { _pGroups = new SfxSlotGroupArr_Impl; if ( _pParentPool ) { // Die Groups im parent Slotpool sind auch hier bekannt SfxSlotGroupArr_Impl& rGroups = *_pParentPool->_pGroups; for ( sal_uInt16 n=0; nAppend( rGroups[n] ); } } if ( !_pTypes ) _pTypes = new SfxSlotTypeArr_Impl; for ( sal_uInt16 nFunc = 0; nFunc < rInterface.Count(); ++nFunc ) { SfxSlot *pDef = rInterface[nFunc]; if ( pDef->GetGroupId() && /* pDef->GetGroupId() != GID_INTERN && */ !_pGroups->Contains(pDef->GetGroupId()) ) { if (pDef->GetGroupId() == GID_INTERN) _pGroups->Insert(0, pDef->GetGroupId()); else _pGroups->Append(pDef->GetGroupId()); } #if 0 const TypeId &rTypeId = pDef->GetType()->Type(); if ( /*rTypeId != TYPE(SfxVoidItem) &&*/ rTypeId != 0 ) { sal_uInt16 nPos; for ( nPos = 0; nPos < _pTypes->Count(); ++nPos ) { if ( _pTypes->GetObject(nPos)->nId == pDef->GetSlotId() ) { DBG_ASSERT( rTypeId == _pTypes->GetObject(nPos)->nType, "same slot id with unequal item types" ); } else if ( _pTypes->GetObject(nPos)->nId > pDef->GetSlotId() ) break; } if ( nPos >= _pTypes->Count() || _pTypes->GetObject(nPos)->nId > pDef->GetSlotId() ) _pTypes->Append( new SfxSlotType_Impl( pDef->GetSlotId(), rTypeId ) ); } #endif } } //==================================================================== TypeId SfxSlotPool::GetSlotType( sal_uInt16 nId ) const { const SfxSlot* pSlot = (const_cast (this))->GetSlot( nId ); return pSlot ? pSlot->GetType()->Type() : 0; /* for ( sal_uInt16 nPos = 0; nPos < _pTypes->Count(); ++nPos ) { if ( _pTypes->GetObject(nPos)->nId == nId ) return _pTypes->GetObject(nPos)->nType; } return _pParentPool ? _pParentPool->GetSlotType( nId ) : 0; */ } //==================================================================== // unregisters the availability of the Interface of functions void SfxSlotPool::ReleaseInterface( SfxInterface& rInterface ) { DBG_MEMTEST(); DBG_ASSERT( _pInterfaces, "releasing SfxInterface, but there are none" ); // remove from the list of SfxInterface instances _pInterfaces->Remove(&rInterface); } //-------------------------------------------------------------------- // get the first SfxMessage for a special Id (e.g. for getting check-mode) const SfxSlot* SfxSlotPool::GetSlot( sal_uInt16 nId ) { DBG_MEMTEST(); DBG_ASSERT( _pInterfaces != 0, "no Interfaces registered" ); // Zun"achst die eigenen Interfaces absuchen for ( sal_uInt16 nInterf = 0; nInterf < _pInterfaces->Count(); ++nInterf ) { const SfxSlot *pDef = _pInterfaces->GetObject(nInterf)->GetSlot(nId); if ( pDef ) return pDef; } // Dann beim eventuell vorhandenen parent versuchen return _pParentPool ? _pParentPool->GetSlot( nId ) : 0; } //-------------------------------------------------------------------- // skips to the next group String SfxSlotPool::SeekGroup( sal_uInt16 nNo ) { DBG_MEMTEST(); DBG_ASSERT( _pInterfaces != 0, "no Interfaces registered" ); // if the group exists, use it if ( _pGroups && nNo < _pGroups->Count() ) { _nCurGroup = nNo; if ( _pParentPool ) { // Meistens stimmt die Reihenfolge der Ids "uberein sal_uInt16 nParentCount = _pParentPool->_pGroups->Count(); if ( nNo < nParentCount && (*_pGroups)[nNo] == (*_pParentPool->_pGroups)[nNo] ) _pParentPool->_nCurGroup = nNo; else { // Ansonsten mu\s gesucht werden // Wenn die Gruppe im parent pool nicht gefunden wird, wird // _nCurGroup au\serhalb des g"ultigen Bereiches gesetzt sal_uInt16 i; for ( i=1; i_pGroups)[i] ) break; _pParentPool->_nCurGroup = i; } } SfxResId aResId( (*_pGroups)[_nCurGroup] ); aResId.SetRT(RSC_STRING); if ( !aResId.GetResMgr()->IsAvailable(aResId) ) { DBG_ERROR( "GroupId-Name nicht im SFX definiert!" ); return String(); } return String( aResId ); } return String(); } //-------------------------------------------------------------------- sal_uInt16 SfxSlotPool::GetGroupCount() { return _pGroups->Count(); } //-------------------------------------------------------------------- // internal search loop const SfxSlot* SfxSlotPool::SeekSlot( sal_uInt16 nStartInterface ) { DBG_MEMTEST(); DBG_ASSERT( _pInterfaces != 0, "no Interfaces registered" ); // Die Numerierung der interfaces startet beim parent pool sal_uInt16 nFirstInterface = _pParentPool ? _pParentPool->_pInterfaces->Count() : 0; // sind wir am Ende des Parent-Pools angekommen? if ( nStartInterface < nFirstInterface && _pParentPool->_nCurGroup >= _pParentPool->_pGroups->Count() ) nStartInterface = nFirstInterface; // liegt das Interface noch im Parent-Pool? if ( nStartInterface < nFirstInterface ) { DBG_ASSERT( _pParentPool, "Kein parent pool!" ); _nCurInterface = nStartInterface; return _pParentPool->SeekSlot( nStartInterface ); } // find the first func-def with the current group id sal_uInt16 nCount = _pInterfaces->Count() + nFirstInterface; for ( _nCurInterface = nStartInterface; _nCurInterface < nCount; ++_nCurInterface ) { SfxInterface* pInterface = (*_pInterfaces)[_nCurInterface-nFirstInterface]; for ( _nCurMsg = 0; _nCurMsg < pInterface->Count(); ++_nCurMsg ) { const SfxSlot* pMsg = (*pInterface)[_nCurMsg]; if ( pMsg->GetGroupId() == _pGroups->GetObject(_nCurGroup) ) return pMsg; } } return 0; } //-------------------------------------------------------------------- // skips to the next func in the current group const SfxSlot* SfxSlotPool::NextSlot() { DBG_MEMTEST(); DBG_ASSERT( _pInterfaces != 0, "no Interfaces registered" ); // Die Numerierung der interfaces startet beim parent pool sal_uInt16 nFirstInterface = _pParentPool ? _pParentPool->_pInterfaces->Count() : 0; if ( _nCurInterface < nFirstInterface && _nCurGroup >= _pParentPool->_pGroups->Count() ) _nCurInterface = nFirstInterface; if ( _nCurInterface < nFirstInterface ) { DBG_ASSERT( _pParentPool, "Kein parent pool!" ); const SfxSlot *pSlot = _pParentPool->NextSlot(); _nCurInterface = _pParentPool->_nCurInterface; if ( pSlot ) return pSlot; if ( _nCurInterface == nFirstInterface ) // parent pool ist fertig return SeekSlot( nFirstInterface ); } sal_uInt16 nInterface = _nCurInterface - nFirstInterface; // possibly we are already at the end if ( nInterface >= _pInterfaces->Count() ) return 0; // look for further matching func-defs within the same Interface SfxInterface* pInterface = (*_pInterfaces)[nInterface]; while ( ++_nCurMsg < pInterface->Count() ) { SfxSlot* pMsg = (*pInterface)[_nCurMsg]; if ( pMsg->GetGroupId() == _pGroups->GetObject(_nCurGroup) ) return pMsg; } return SeekSlot(++_nCurInterface ); } //-------------------------------------------------------------------- // SlotName erfragen, gfs. mit HilfeText //-------------------------------------------------------------------- SfxInterface* SfxSlotPool::FirstInterface() { _nCurInterface = 0; if ( !_pInterfaces || !_pInterfaces->Count() ) return 0; return _pParentPool ? _pParentPool->FirstInterface() : (*_pInterfaces)[0]; } //-------------------------------------------------------------------- SfxInterface* SfxSlotPool::NextInterface() { _nCurInterface++; sal_uInt16 nFirstInterface = _pParentPool ? _pParentPool->_pInterfaces->Count() : 0; if ( _nCurInterface < nFirstInterface ) return (*_pParentPool->_pInterfaces)[_nCurInterface]; sal_uInt16 nInterface = _nCurInterface - nFirstInterface; return nInterface < _pInterfaces->Count() ? (*_pInterfaces)[nInterface] : 0; } const SfxSlot* SfxSlotPool::GetUnoSlot( const String& rName ) { const SfxSlot *pSlot = NULL; for ( sal_uInt16 nInterface=0; nInterface<_pInterfaces->Count(); nInterface++ ) { pSlot = (*_pInterfaces)[nInterface]->GetSlot( rName ); if ( pSlot ) break; } if ( !pSlot && _pParentPool ) pSlot = _pParentPool->GetUnoSlot( rName ); return pSlot; } SfxSlotPool& SfxSlotPool::GetSlotPool( SfxViewFrame *pFrame ) { SfxModule *pMod = SfxModule::GetActiveModule( pFrame ); if ( pMod && pMod->GetSlotPool() ) return *pMod->GetSlotPool(); else return *SFX_APP()->Get_Impl()->pSlotPool; }