1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
20 #include <sal/log.hxx>
21 #include <osl/diagnose.h>
24 #include <appdata.hxx>
25 #include <sfx2/msgpool.hxx>
26 #include <sfx2/msg.hxx>
27 #include <sfx2/app.hxx>
28 #include <sfx2/objface.hxx>
29 #include <sfx2/sfxresid.hxx>
30 #include <sfx2/module.hxx>
32 #include <sfx2/strings.hrc>
34 SfxSlotPool::SfxSlotPool(SfxSlotPool
*pParent
)
35 : _pParentPool( pParent
)
42 SfxSlotPool::~SfxSlotPool()
44 _pParentPool
= nullptr;
45 // swap out _vInterfaces because ~SfxInterface() might call ReleaseInterface()
46 std::vector
<SfxInterface
*> tmpInterfaces
;
47 tmpInterfaces
.swap(_vInterfaces
);
48 for ( SfxInterface
*pIF
: tmpInterfaces
)
54 TranslateId
getGidResId(SfxGroupId nId
)
56 if (nId
== SfxGroupId::Intern
)
57 return STR_GID_INTERN
;
58 else if (nId
== SfxGroupId::Application
)
59 return STR_GID_APPLICATION
;
60 else if (nId
== SfxGroupId::View
)
62 else if (nId
== SfxGroupId::Document
)
63 return STR_GID_DOCUMENT
;
64 else if (nId
== SfxGroupId::Edit
)
66 else if (nId
== SfxGroupId::Macro
)
68 else if (nId
== SfxGroupId::Options
)
69 return STR_GID_OPTIONS
;
70 else if (nId
== SfxGroupId::Math
)
72 else if (nId
== SfxGroupId::Navigator
)
73 return STR_GID_NAVIGATOR
;
74 else if (nId
== SfxGroupId::Insert
)
75 return STR_GID_INSERT
;
76 else if (nId
== SfxGroupId::Format
)
77 return STR_GID_FORMAT
;
78 else if (nId
== SfxGroupId::Template
)
79 return STR_GID_TEMPLATE
;
80 else if (nId
== SfxGroupId::Text
)
82 else if (nId
== SfxGroupId::Frame
)
84 else if (nId
== SfxGroupId::Graphic
)
85 return STR_GID_GRAPHIC
;
86 else if (nId
== SfxGroupId::Table
)
88 else if (nId
== SfxGroupId::Enumeration
)
89 return STR_GID_ENUMERATION
;
90 else if (nId
== SfxGroupId::Data
)
92 else if (nId
== SfxGroupId::Special
)
93 return STR_GID_SPECIAL
;
94 else if (nId
== SfxGroupId::Image
)
96 else if (nId
== SfxGroupId::Chart
)
98 else if (nId
== SfxGroupId::Explorer
)
99 return STR_GID_EXPLORER
;
100 else if (nId
== SfxGroupId::Connector
)
101 return STR_GID_CONNECTOR
;
102 else if (nId
== SfxGroupId::Modify
)
103 return STR_GID_MODIFY
;
104 else if (nId
== SfxGroupId::Drawing
)
105 return STR_GID_DRAWING
;
106 else if (nId
== SfxGroupId::Controls
)
107 return STR_GID_CONTROLS
;
112 // registers the availability of the Interface of functions
114 void SfxSlotPool::RegisterInterface( SfxInterface
& rInterface
)
116 // add to the list of SfxObjectInterface instances
117 _vInterfaces
.push_back(&rInterface
);
119 // Stop at a (single) Null-slot (for syntactic reasons the interfaces
120 // always contain at least one slot)
121 if ( rInterface
.Count() != 0 && !rInterface
.pSlots
[0].nSlotId
)
124 // possibly add Interface-id and group-ids of funcs to the list of groups
127 // The Groups in parent Slotpool are also known here
128 _vGroups
.insert( _vGroups
.end(), _pParentPool
->_vGroups
.begin(), _pParentPool
->_vGroups
.end() );
131 for ( size_t nFunc
= 0; nFunc
< rInterface
.Count(); ++nFunc
)
133 SfxSlot
&rDef
= rInterface
.pSlots
[nFunc
];
134 if ( rDef
.GetGroupId() != SfxGroupId::NONE
&&
135 std::find(_vGroups
.begin(), _vGroups
.end(), rDef
.GetGroupId()) == _vGroups
.end() )
137 if (rDef
.GetGroupId() == SfxGroupId::Intern
)
138 _vGroups
.insert(_vGroups
.begin(), rDef
.GetGroupId());
140 _vGroups
.push_back(rDef
.GetGroupId());
146 const std::type_info
* SfxSlotPool::GetSlotType( sal_uInt16 nId
) const
148 const SfxSlot
* pSlot
= GetSlot( nId
);
149 return pSlot
? pSlot
->GetType()->Type() : nullptr;
153 // get the first SfxMessage for a special Id (e.g. for getting check-mode)
155 const SfxSlot
* SfxSlotPool::GetSlot( sal_uInt16 nId
) const
157 // First, search their own interfaces
158 for (SfxInterface
* _pInterface
: _vInterfaces
)
160 const SfxSlot
*pDef
= _pInterface
->GetSlot(nId
);
165 // Then try any of the possible existing parent
166 return _pParentPool
? _pParentPool
->GetSlot( nId
) : nullptr;
170 // skips to the next group
172 OUString
SfxSlotPool::SeekGroup( sal_uInt16 nNo
)
174 // if the group exists, use it
175 if ( nNo
< _vGroups
.size() )
180 // In most cases, the order of the IDs agree
181 sal_uInt16 nParentCount
= _pParentPool
->_vGroups
.size();
182 if ( nNo
< nParentCount
&& _vGroups
[nNo
] == _pParentPool
->_vGroups
[nNo
] )
183 _pParentPool
->_nCurGroup
= nNo
;
186 // Otherwise search. If the group is not found in the parent
187 // pool, _nCurGroup is set outside the valid range
189 for ( i
=1; i
<nParentCount
; i
++ )
190 if ( _vGroups
[nNo
] == _pParentPool
->_vGroups
[i
] )
192 _pParentPool
->_nCurGroup
= i
;
196 TranslateId pResId
= getGidResId(_vGroups
[_nCurGroup
]);
199 OSL_FAIL( "GroupId-Name not defined in SFX!" );
203 return SfxResId(pResId
);
210 sal_uInt16
SfxSlotPool::GetGroupCount() const
212 return _vGroups
.size();
216 // internal search loop
218 const SfxSlot
* SfxSlotPool::SeekSlot( sal_uInt16 nStartInterface
)
220 // The numbering starts at the interfaces of the parent pool
221 sal_uInt16 nFirstInterface
= _pParentPool
? _pParentPool
->_vInterfaces
.size() : 0;
223 // have reached the end of the Parent-Pools?
224 if ( nStartInterface
< nFirstInterface
&&
225 _pParentPool
->_nCurGroup
>= _pParentPool
->_vGroups
.size() )
226 nStartInterface
= nFirstInterface
;
228 // Is the Interface still in the Parent-Pool?
229 if ( nStartInterface
< nFirstInterface
)
231 SAL_WARN_IF(!_pParentPool
, "sfx.control", "No parent pool!");
232 _nCurInterface
= nStartInterface
;
233 return _pParentPool
->SeekSlot( nStartInterface
);
236 // find the first func-def with the current group id
237 sal_uInt16 nCount
= _vInterfaces
.size() + nFirstInterface
;
238 for ( _nCurInterface
= nStartInterface
;
239 _nCurInterface
< nCount
;
242 SfxInterface
* pInterface
= _vInterfaces
[_nCurInterface
-nFirstInterface
];
244 _nCurMsg
< pInterface
->Count();
247 const SfxSlot
& rMsg
= pInterface
->pSlots
[_nCurMsg
];
248 if (rMsg
.GetGroupId() == _vGroups
.at(_nCurGroup
))
257 // skips to the next func in the current group
259 const SfxSlot
* SfxSlotPool::NextSlot()
261 // The numbering starts at the interfaces of the parent pool
262 sal_uInt16 nFirstInterface
= _pParentPool
? _pParentPool
->_vInterfaces
.size() : 0;
264 if ( _nCurInterface
< nFirstInterface
&& _nCurGroup
>= _pParentPool
->_vGroups
.size() )
265 _nCurInterface
= nFirstInterface
;
267 if ( _nCurInterface
< nFirstInterface
)
269 SAL_WARN_IF(!_pParentPool
, "sfx.control", "No parent pool!");
270 const SfxSlot
*pSlot
= _pParentPool
->NextSlot();
271 _nCurInterface
= _pParentPool
->_nCurInterface
;
274 if ( _nCurInterface
== nFirstInterface
)
275 // parent pool is ready
276 return SeekSlot( nFirstInterface
);
279 sal_uInt16 nInterface
= _nCurInterface
- nFirstInterface
;
280 // possibly we are already at the end
281 if ( nInterface
>= _vInterfaces
.size() )
284 // look for further matching func-defs within the same Interface
285 SfxInterface
* pInterface
= _vInterfaces
[nInterface
];
286 while ( ++_nCurMsg
< pInterface
->Count() )
288 SfxSlot
& rMsg
= pInterface
->pSlots
[_nCurMsg
];
289 if (rMsg
.GetGroupId() == _vGroups
.at(_nCurGroup
))
293 return SeekSlot(++_nCurInterface
);
297 // Query SlotName with help text
300 const SfxSlot
* SfxSlotPool::GetUnoSlot( const OUString
& rName
) const
302 const SfxSlot
*pSlot
= nullptr;
303 for (auto const & nInterface
: _vInterfaces
)
305 pSlot
= nInterface
->GetSlot( rName
);
310 if ( !pSlot
&& _pParentPool
)
311 pSlot
= _pParentPool
->GetUnoSlot( rName
);
316 SfxSlotPool
& SfxSlotPool::GetSlotPool( SfxViewFrame
*pFrame
)
318 SfxModule
*pMod
= SfxModule::GetActiveModule( pFrame
);
319 if ( pMod
&& pMod
->GetSlotPool() )
320 return *pMod
->GetSlotPool();
322 return *SfxGetpApp()->Get_Impl()->pSlotPool
;
326 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */