1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: msgpool.cxx,v $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_sfx2.hxx"
33 #include <tools/stream.hxx>
34 #include <rsc/rscsfx.hxx>
39 #include "appdata.hxx"
40 #include <sfx2/msgpool.hxx>
41 #include <sfx2/minarray.hxx>
42 #include <sfx2/msg.hxx>
43 #include <sfx2/app.hxx>
44 #include <sfx2/objface.hxx>
45 #include "sfxtypes.hxx"
46 #include <sfx2/macrconf.hxx>
47 #include "sfxresid.hxx"
48 #include "arrdecl.hxx"
49 #include <sfx2/module.hxx>
51 #include <sfx2/sfx.hrc>
53 //====================================================================
55 struct SfxSIDRegistration_Impl
62 struct SfxSlotType_Impl
67 SfxSlotType_Impl( USHORT nTheId
, TypeId nTheType
):
68 nId(nTheId
), nType(nTheType
)
72 DECL_2BYTEARRAY(SfxSlotGroupArr_Impl
, USHORT
, 6, 4)
73 DECL_PTRARRAY(SfxInterfaceArr_Impl
, SfxInterface
*, 6, 3)
74 DECL_PTRARRAY(SfxSlotTypeArr_Impl
, SfxSlotType_Impl
*, 8, 8)
77 //====================================================================
79 SfxSlotPool::SfxSlotPool( SfxSlotPool
*pParent
, ResMgr
* pResManager
)
82 , _pParentPool( pParent
)
83 , _pResMgr( pResManager
)
91 _pResMgr
= SfxApplication::GetOrCreate()->GetOffResManager_Impl();
94 //====================================================================
96 SfxSlotPool::~SfxSlotPool()
99 for ( SfxInterface
*pIF
= FirstInterface(); pIF
; pIF
= FirstInterface() )
105 for ( USHORT n
=_pTypes
->Count(); n
--; )
106 delete _pTypes
->GetObject(n
);
111 //====================================================================
113 // registers the availability of the Interface of functions
115 void SfxSlotPool::RegisterInterface( SfxInterface
& rInterface
)
119 // add to the list of SfxObjectInterface instances
120 if ( _pInterfaces
== 0 )
121 _pInterfaces
= new SfxInterfaceArr_Impl
;
122 _pInterfaces
->Append(&rInterface
);
124 // bei einem (einzelnen) Null-Slot abbrechen (aus syntaktischen Gr"unden
125 // enthalten interfaces immer mindestens einen Slot)
126 if ( rInterface
.Count() == 1 && !rInterface
[0]->nSlotId
)
129 // possibly add Interface-id and group-ids of funcs to the list of groups
132 _pGroups
= new SfxSlotGroupArr_Impl
;
136 // Die Groups im parent Slotpool sind auch hier bekannt
137 SfxSlotGroupArr_Impl
& rGroups
= *_pParentPool
->_pGroups
;
138 for ( USHORT n
=0; n
<rGroups
.Count(); n
++ )
139 _pGroups
->Append( rGroups
[n
] );
144 _pTypes
= new SfxSlotTypeArr_Impl
;
145 for ( USHORT nFunc
= 0; nFunc
< rInterface
.Count(); ++nFunc
)
147 SfxSlot
*pDef
= rInterface
[nFunc
];
148 if ( pDef
->GetGroupId() && /* pDef->GetGroupId() != GID_INTERN && */
149 !_pGroups
->Contains(pDef
->GetGroupId()) )
151 if (pDef
->GetGroupId() == GID_INTERN
)
152 _pGroups
->Insert(0, pDef
->GetGroupId());
154 _pGroups
->Append(pDef
->GetGroupId());
157 const TypeId
&rTypeId
= pDef
->GetType()->Type();
158 if ( /*rTypeId != TYPE(SfxVoidItem) &&*/ rTypeId
!= 0 )
161 for ( nPos
= 0; nPos
< _pTypes
->Count(); ++nPos
)
163 if ( _pTypes
->GetObject(nPos
)->nId
== pDef
->GetSlotId() )
165 DBG_ASSERT( rTypeId
== _pTypes
->GetObject(nPos
)->nType
,
166 "same slot id with unequal item types" );
168 else if ( _pTypes
->GetObject(nPos
)->nId
> pDef
->GetSlotId() )
171 if ( nPos
>= _pTypes
->Count() ||
172 _pTypes
->GetObject(nPos
)->nId
> pDef
->GetSlotId() )
173 _pTypes
->Append( new SfxSlotType_Impl( pDef
->GetSlotId(), rTypeId
) );
179 //====================================================================
181 TypeId
SfxSlotPool::GetSlotType( USHORT nId
) const
183 const SfxSlot
* pSlot
= (const_cast <SfxSlotPool
*> (this))->GetSlot( nId
);
184 return pSlot
? pSlot
->GetType()->Type() : 0;
186 for ( USHORT nPos = 0; nPos < _pTypes->Count(); ++nPos )
188 if ( _pTypes->GetObject(nPos)->nId == nId )
189 return _pTypes->GetObject(nPos)->nType;
191 return _pParentPool ? _pParentPool->GetSlotType( nId ) : 0;
195 //====================================================================
197 // unregisters the availability of the Interface of functions
199 void SfxSlotPool::ReleaseInterface( SfxInterface
& rInterface
)
202 DBG_ASSERT( _pInterfaces
, "releasing SfxInterface, but there are none" );
203 // remove from the list of SfxInterface instances
204 _pInterfaces
->Remove(&rInterface
);
207 //--------------------------------------------------------------------
209 // get the first SfxMessage for a special Id (e.g. for getting check-mode)
211 const SfxSlot
* SfxSlotPool::GetSlot( USHORT nId
)
214 DBG_ASSERT( _pInterfaces
!= 0, "no Interfaces registered" );
216 // Zun"achst die eigenen Interfaces absuchen
217 for ( USHORT nInterf
= 0; nInterf
< _pInterfaces
->Count(); ++nInterf
)
219 const SfxSlot
*pDef
= _pInterfaces
->GetObject(nInterf
)->GetSlot(nId
);
224 // Dann beim eventuell vorhandenen parent versuchen
225 return _pParentPool
? _pParentPool
->GetSlot( nId
) : 0;
228 //--------------------------------------------------------------------
230 // skips to the next group
232 String
SfxSlotPool::SeekGroup( USHORT nNo
)
235 DBG_ASSERT( _pInterfaces
!= 0, "no Interfaces registered" );
237 // if the group exists, use it
238 if ( _pGroups
&& nNo
< _pGroups
->Count() )
243 // Meistens stimmt die Reihenfolge der Ids "uberein
244 USHORT nParentCount
= _pParentPool
->_pGroups
->Count();
245 if ( nNo
< nParentCount
&& (*_pGroups
)[nNo
] == (*_pParentPool
->_pGroups
)[nNo
] )
246 _pParentPool
->_nCurGroup
= nNo
;
249 // Ansonsten mu\s gesucht werden
250 // Wenn die Gruppe im parent pool nicht gefunden wird, wird
251 // _nCurGroup au\serhalb des g"ultigen Bereiches gesetzt
253 for ( i
=1; i
<nParentCount
; i
++ )
254 if ( (*_pGroups
)[nNo
] == (*_pParentPool
->_pGroups
)[i
] )
256 _pParentPool
->_nCurGroup
= i
;
260 SfxResId
aResId( (*_pGroups
)[_nCurGroup
] );
261 aResId
.SetRT(RSC_STRING
);
262 if ( !aResId
.GetResMgr()->IsAvailable(aResId
) )
264 DBG_ERROR( "GroupId-Name nicht im SFX definiert!" );
268 return String( aResId
);
275 //--------------------------------------------------------------------
277 USHORT
SfxSlotPool::GetGroupCount()
279 return _pGroups
->Count();
283 //--------------------------------------------------------------------
285 // internal search loop
287 const SfxSlot
* SfxSlotPool::SeekSlot( USHORT nStartInterface
)
290 DBG_ASSERT( _pInterfaces
!= 0, "no Interfaces registered" );
292 // Die Numerierung der interfaces startet beim parent pool
293 USHORT nFirstInterface
= _pParentPool
? _pParentPool
->_pInterfaces
->Count() : 0;
295 // sind wir am Ende des Parent-Pools angekommen?
296 if ( nStartInterface
< nFirstInterface
&&
297 _pParentPool
->_nCurGroup
>= _pParentPool
->_pGroups
->Count() )
298 nStartInterface
= nFirstInterface
;
300 // liegt das Interface noch im Parent-Pool?
301 if ( nStartInterface
< nFirstInterface
)
303 DBG_ASSERT( _pParentPool
, "Kein parent pool!" );
304 _nCurInterface
= nStartInterface
;
305 return _pParentPool
->SeekSlot( nStartInterface
);
308 // find the first func-def with the current group id
309 USHORT nCount
= _pInterfaces
->Count() + nFirstInterface
;
310 for ( _nCurInterface
= nStartInterface
;
311 _nCurInterface
< nCount
;
314 SfxInterface
* pInterface
= (*_pInterfaces
)[_nCurInterface
-nFirstInterface
];
316 _nCurMsg
< pInterface
->Count();
319 const SfxSlot
* pMsg
= (*pInterface
)[_nCurMsg
];
320 if ( pMsg
->GetGroupId() == _pGroups
->GetObject(_nCurGroup
) )
328 //--------------------------------------------------------------------
330 // skips to the next func in the current group
332 const SfxSlot
* SfxSlotPool::NextSlot()
335 DBG_ASSERT( _pInterfaces
!= 0, "no Interfaces registered" );
337 // Die Numerierung der interfaces startet beim parent pool
338 USHORT nFirstInterface
= _pParentPool
? _pParentPool
->_pInterfaces
->Count() : 0;
340 if ( _nCurInterface
< nFirstInterface
&& _nCurGroup
>= _pParentPool
->_pGroups
->Count() )
341 _nCurInterface
= nFirstInterface
;
343 if ( _nCurInterface
< nFirstInterface
)
345 DBG_ASSERT( _pParentPool
, "Kein parent pool!" );
346 const SfxSlot
*pSlot
= _pParentPool
->NextSlot();
347 _nCurInterface
= _pParentPool
->_nCurInterface
;
350 if ( _nCurInterface
== nFirstInterface
)
351 // parent pool ist fertig
352 return SeekSlot( nFirstInterface
);
355 USHORT nInterface
= _nCurInterface
- nFirstInterface
;
356 // possibly we are already at the end
357 if ( nInterface
>= _pInterfaces
->Count() )
360 // look for further matching func-defs within the same Interface
361 SfxInterface
* pInterface
= (*_pInterfaces
)[nInterface
];
362 while ( ++_nCurMsg
< pInterface
->Count() )
364 SfxSlot
* pMsg
= (*pInterface
)[_nCurMsg
];
365 if ( pMsg
->GetGroupId() == _pGroups
->GetObject(_nCurGroup
) )
369 return SeekSlot(++_nCurInterface
);
373 //--------------------------------------------------------------------
375 // SlotName erfragen, gfs. mit HilfeText
377 //--------------------------------------------------------------------
379 SfxInterface
* SfxSlotPool::FirstInterface()
382 if ( !_pInterfaces
|| !_pInterfaces
->Count() )
384 return _pParentPool
? _pParentPool
->FirstInterface() : (*_pInterfaces
)[0];
388 //--------------------------------------------------------------------
390 SfxInterface
* SfxSlotPool::NextInterface()
393 USHORT nFirstInterface
= _pParentPool
? _pParentPool
->_pInterfaces
->Count() : 0;
394 if ( _nCurInterface
< nFirstInterface
)
395 return (*_pParentPool
->_pInterfaces
)[_nCurInterface
];
396 USHORT nInterface
= _nCurInterface
- nFirstInterface
;
397 return nInterface
< _pInterfaces
->Count() ? (*_pInterfaces
)[nInterface
] : 0;
400 const SfxSlot
* SfxSlotPool::GetUnoSlot( const String
& rName
)
402 const SfxSlot
*pSlot
= NULL
;
403 for ( USHORT nInterface
=0; nInterface
<_pInterfaces
->Count(); nInterface
++ )
405 pSlot
= (*_pInterfaces
)[nInterface
]->GetSlot( rName
);
410 if ( !pSlot
&& _pParentPool
)
411 pSlot
= _pParentPool
->GetUnoSlot( rName
);
416 SfxSlotPool
& SfxSlotPool::GetSlotPool( SfxViewFrame
*pFrame
)
418 SfxModule
*pMod
= SfxModule::GetActiveModule( pFrame
);
419 if ( pMod
&& pMod
->GetSlotPool() )
420 return *pMod
->GetSlotPool();
422 return *SFX_APP()->Get_Impl()->pSlotPool
;