/src/libreoffice/sfx2/source/control/msgpool.cxx
Line | Count | Source |
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 <sal/log.hxx> |
21 | | #include <osl/diagnose.h> |
22 | | |
23 | | // due to pSlotPool |
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> |
31 | | |
32 | | #include <sfx2/strings.hrc> |
33 | | |
34 | | SfxSlotPool::SfxSlotPool(SfxSlotPool *pParent) |
35 | 52 | : _pParentPool( pParent ) |
36 | 52 | , _nCurGroup(0) |
37 | 52 | , _nCurInterface(0) |
38 | 52 | , _nCurMsg(0) |
39 | 52 | { |
40 | 52 | } |
41 | | |
42 | | SfxSlotPool::~SfxSlotPool() |
43 | 0 | { |
44 | 0 | _pParentPool = nullptr; |
45 | | // swap out _vInterfaces because ~SfxInterface() might call ReleaseInterface() |
46 | 0 | std::vector<SfxInterface*> tmpInterfaces; |
47 | 0 | tmpInterfaces.swap(_vInterfaces); |
48 | 0 | for ( SfxInterface *pIF : tmpInterfaces ) |
49 | 0 | delete pIF; |
50 | 0 | } |
51 | | |
52 | | namespace |
53 | | { |
54 | | TranslateId getGidResId(SfxGroupId nId) |
55 | 0 | { |
56 | 0 | if (nId == SfxGroupId::Intern) |
57 | 0 | return STR_GID_INTERN; |
58 | 0 | else if (nId == SfxGroupId::Application) |
59 | 0 | return STR_GID_APPLICATION; |
60 | 0 | else if (nId == SfxGroupId::View) |
61 | 0 | return STR_GID_VIEW; |
62 | 0 | else if (nId == SfxGroupId::Document) |
63 | 0 | return STR_GID_DOCUMENT; |
64 | 0 | else if (nId == SfxGroupId::Edit) |
65 | 0 | return STR_GID_EDIT; |
66 | 0 | else if (nId == SfxGroupId::Macro) |
67 | 0 | return STR_GID_MACRO; |
68 | 0 | else if (nId == SfxGroupId::Options) |
69 | 0 | return STR_GID_OPTIONS; |
70 | 0 | else if (nId == SfxGroupId::Math) |
71 | 0 | return STR_GID_MATH; |
72 | 0 | else if (nId == SfxGroupId::Navigator) |
73 | 0 | return STR_GID_NAVIGATOR; |
74 | 0 | else if (nId == SfxGroupId::Insert) |
75 | 0 | return STR_GID_INSERT; |
76 | 0 | else if (nId == SfxGroupId::Format) |
77 | 0 | return STR_GID_FORMAT; |
78 | 0 | else if (nId == SfxGroupId::Template) |
79 | 0 | return STR_GID_TEMPLATE; |
80 | 0 | else if (nId == SfxGroupId::Text) |
81 | 0 | return STR_GID_TEXT; |
82 | 0 | else if (nId == SfxGroupId::Frame) |
83 | 0 | return STR_GID_FRAME; |
84 | 0 | else if (nId == SfxGroupId::Graphic) |
85 | 0 | return STR_GID_GRAPHIC; |
86 | 0 | else if (nId == SfxGroupId::Table) |
87 | 0 | return STR_GID_TABLE; |
88 | 0 | else if (nId == SfxGroupId::Enumeration) |
89 | 0 | return STR_GID_ENUMERATION; |
90 | 0 | else if (nId == SfxGroupId::Data) |
91 | 0 | return STR_GID_DATA; |
92 | 0 | else if (nId == SfxGroupId::Special) |
93 | 0 | return STR_GID_SPECIAL; |
94 | 0 | else if (nId == SfxGroupId::Image) |
95 | 0 | return STR_GID_IMAGE; |
96 | 0 | else if (nId == SfxGroupId::Chart) |
97 | 0 | return STR_GID_CHART; |
98 | 0 | else if (nId == SfxGroupId::Explorer) |
99 | 0 | return STR_GID_EXPLORER; |
100 | 0 | else if (nId == SfxGroupId::Connector) |
101 | 0 | return STR_GID_CONNECTOR; |
102 | 0 | else if (nId == SfxGroupId::Modify) |
103 | 0 | return STR_GID_MODIFY; |
104 | 0 | else if (nId == SfxGroupId::Drawing) |
105 | 0 | return STR_GID_DRAWING; |
106 | 0 | else if (nId == SfxGroupId::Controls) |
107 | 0 | return STR_GID_CONTROLS; |
108 | 0 | return {}; |
109 | 0 | } |
110 | | } |
111 | | |
112 | | // registers the availability of the Interface of functions |
113 | | |
114 | | void SfxSlotPool::RegisterInterface( SfxInterface& rInterface ) |
115 | 716 | { |
116 | | // add to the list of SfxObjectInterface instances |
117 | 716 | _vInterfaces.push_back(&rInterface); |
118 | | |
119 | | // Stop at a (single) Null-slot (for syntactic reasons the interfaces |
120 | | // always contain at least one slot) |
121 | 716 | if ( rInterface.Count() != 0 && !rInterface.pSlots[0].nSlotId ) |
122 | 88 | return; |
123 | | |
124 | | // possibly add Interface-id and group-ids of funcs to the list of groups |
125 | 628 | if ( _pParentPool ) |
126 | 499 | { |
127 | | // The Groups in parent Slotpool are also known here |
128 | 499 | _vGroups.insert( _vGroups.end(), _pParentPool->_vGroups.begin(), _pParentPool->_vGroups.end() ); |
129 | 499 | } |
130 | | |
131 | 51.9k | for ( size_t nFunc = 0; nFunc < rInterface.Count(); ++nFunc ) |
132 | 51.2k | { |
133 | 51.2k | const SfxSlot &rDef = rInterface.pSlots[nFunc]; |
134 | 51.2k | if ( rDef.GetGroupId() != SfxGroupId::NONE && |
135 | 50.2k | std::find(_vGroups.begin(), _vGroups.end(), rDef.GetGroupId()) == _vGroups.end() ) |
136 | 616 | { |
137 | 616 | if (rDef.GetGroupId() == SfxGroupId::Intern) |
138 | 26 | _vGroups.insert(_vGroups.begin(), rDef.GetGroupId()); |
139 | 590 | else |
140 | 590 | _vGroups.push_back(rDef.GetGroupId()); |
141 | 616 | } |
142 | 51.2k | } |
143 | 628 | } |
144 | | |
145 | | |
146 | | const std::type_info* SfxSlotPool::GetSlotType( sal_uInt16 nId ) const |
147 | 0 | { |
148 | 0 | const SfxSlot* pSlot = GetSlot( nId ); |
149 | 0 | return pSlot ? pSlot->GetType()->Type() : nullptr; |
150 | 0 | } |
151 | | |
152 | | |
153 | | // get the first SfxMessage for a special Id (e.g. for getting check-mode) |
154 | | |
155 | | const SfxSlot* SfxSlotPool::GetSlot( sal_uInt16 nId ) const |
156 | 737k | { |
157 | | // First, search their own interfaces |
158 | 737k | for (SfxInterface* _pInterface : _vInterfaces) |
159 | 6.67M | { |
160 | 6.67M | const SfxSlot *pDef = _pInterface->GetSlot(nId); |
161 | 6.67M | if ( pDef ) |
162 | 580k | return pDef; |
163 | 6.67M | } |
164 | | |
165 | | // Then try any of the possible existing parent |
166 | 156k | return _pParentPool ? _pParentPool->GetSlot( nId ) : nullptr; |
167 | 737k | } |
168 | | |
169 | | |
170 | | // skips to the next group |
171 | | |
172 | | OUString SfxSlotPool::SeekGroup( sal_uInt16 nNo ) |
173 | 0 | { |
174 | | // if the group exists, use it |
175 | 0 | if ( nNo < _vGroups.size() ) |
176 | 0 | { |
177 | 0 | _nCurGroup = nNo; |
178 | 0 | if ( _pParentPool ) |
179 | 0 | { |
180 | | // In most cases, the order of the IDs agree |
181 | 0 | sal_uInt16 nParentCount = _pParentPool->_vGroups.size(); |
182 | 0 | if ( nNo < nParentCount && _vGroups[nNo] == _pParentPool->_vGroups[nNo] ) |
183 | 0 | _pParentPool->_nCurGroup = nNo; |
184 | 0 | else |
185 | 0 | { |
186 | | // Otherwise search. If the group is not found in the parent |
187 | | // pool, _nCurGroup is set outside the valid range |
188 | 0 | sal_uInt16 i; |
189 | 0 | for ( i=1; i<nParentCount; i++ ) |
190 | 0 | if ( _vGroups[nNo] == _pParentPool->_vGroups[i] ) |
191 | 0 | break; |
192 | 0 | _pParentPool->_nCurGroup = i; |
193 | 0 | } |
194 | 0 | } |
195 | |
|
196 | 0 | TranslateId pResId = getGidResId(_vGroups[_nCurGroup]); |
197 | 0 | if (!pResId) |
198 | 0 | { |
199 | 0 | OSL_FAIL( "GroupId-Name not defined in SFX!" ); |
200 | 0 | return OUString(); |
201 | 0 | } |
202 | | |
203 | 0 | return SfxResId(pResId); |
204 | 0 | } |
205 | | |
206 | 0 | return OUString(); |
207 | 0 | } |
208 | | |
209 | | |
210 | | sal_uInt16 SfxSlotPool::GetGroupCount() const |
211 | 0 | { |
212 | 0 | return _vGroups.size(); |
213 | 0 | } |
214 | | |
215 | | |
216 | | // internal search loop |
217 | | |
218 | | const SfxSlot* SfxSlotPool::SeekSlot( sal_uInt16 nStartInterface ) |
219 | 0 | { |
220 | | // The numbering starts at the interfaces of the parent pool |
221 | 0 | sal_uInt16 nFirstInterface = _pParentPool ? _pParentPool->_vInterfaces.size() : 0; |
222 | | |
223 | | // have reached the end of the Parent-Pools? |
224 | 0 | if ( nStartInterface < nFirstInterface && |
225 | 0 | _pParentPool->_nCurGroup >= _pParentPool->_vGroups.size() ) |
226 | 0 | nStartInterface = nFirstInterface; |
227 | | |
228 | | // Is the Interface still in the Parent-Pool? |
229 | 0 | if ( nStartInterface < nFirstInterface ) |
230 | 0 | { |
231 | 0 | SAL_WARN_IF(!_pParentPool, "sfx.control", "No parent pool!"); |
232 | 0 | _nCurInterface = nStartInterface; |
233 | 0 | return _pParentPool->SeekSlot( nStartInterface ); |
234 | 0 | } |
235 | | |
236 | | // find the first func-def with the current group id |
237 | 0 | sal_uInt16 nCount = _vInterfaces.size() + nFirstInterface; |
238 | 0 | for ( _nCurInterface = nStartInterface; |
239 | 0 | _nCurInterface < nCount; |
240 | 0 | ++_nCurInterface ) |
241 | 0 | { |
242 | 0 | SfxInterface* pInterface = _vInterfaces[_nCurInterface-nFirstInterface]; |
243 | 0 | for ( _nCurMsg = 0; |
244 | 0 | _nCurMsg < pInterface->Count(); |
245 | 0 | ++_nCurMsg ) |
246 | 0 | { |
247 | 0 | const SfxSlot& rMsg = pInterface->pSlots[_nCurMsg]; |
248 | 0 | if (rMsg.GetGroupId() == _vGroups.at(_nCurGroup)) |
249 | 0 | return &rMsg; |
250 | 0 | } |
251 | 0 | } |
252 | | |
253 | 0 | return nullptr; |
254 | 0 | } |
255 | | |
256 | | |
257 | | // skips to the next func in the current group |
258 | | |
259 | | const SfxSlot* SfxSlotPool::NextSlot() |
260 | 0 | { |
261 | | // The numbering starts at the interfaces of the parent pool |
262 | 0 | sal_uInt16 nFirstInterface = _pParentPool ? _pParentPool->_vInterfaces.size() : 0; |
263 | |
|
264 | 0 | if ( _nCurInterface < nFirstInterface && _nCurGroup >= _pParentPool->_vGroups.size() ) |
265 | 0 | _nCurInterface = nFirstInterface; |
266 | |
|
267 | 0 | if ( _nCurInterface < nFirstInterface ) |
268 | 0 | { |
269 | 0 | SAL_WARN_IF(!_pParentPool, "sfx.control", "No parent pool!"); |
270 | 0 | const SfxSlot *pSlot = _pParentPool->NextSlot(); |
271 | 0 | _nCurInterface = _pParentPool->_nCurInterface; |
272 | 0 | if ( pSlot ) |
273 | 0 | return pSlot; |
274 | 0 | if ( _nCurInterface == nFirstInterface ) |
275 | | // parent pool is ready |
276 | 0 | return SeekSlot( nFirstInterface ); |
277 | 0 | } |
278 | | |
279 | 0 | sal_uInt16 nInterface = _nCurInterface - nFirstInterface; |
280 | | // possibly we are already at the end |
281 | 0 | if ( nInterface >= _vInterfaces.size() ) |
282 | 0 | return nullptr; |
283 | | |
284 | | // look for further matching func-defs within the same Interface |
285 | 0 | SfxInterface* pInterface = _vInterfaces[nInterface]; |
286 | 0 | while ( ++_nCurMsg < pInterface->Count() ) |
287 | 0 | { |
288 | 0 | const SfxSlot& rMsg = pInterface->pSlots[_nCurMsg]; |
289 | 0 | if (rMsg.GetGroupId() == _vGroups.at(_nCurGroup)) |
290 | 0 | return &rMsg; |
291 | 0 | } |
292 | | |
293 | 0 | return SeekSlot(++_nCurInterface ); |
294 | 0 | } |
295 | | |
296 | | |
297 | | // Query SlotName with help text |
298 | | |
299 | | |
300 | | const SfxSlot* SfxSlotPool::GetUnoSlot( const OUString& rName ) const |
301 | 0 | { |
302 | 0 | const SfxSlot *pSlot = nullptr; |
303 | 0 | for (auto const & nInterface: _vInterfaces) |
304 | 0 | { |
305 | 0 | pSlot = nInterface->GetSlot( rName ); |
306 | 0 | if ( pSlot ) |
307 | 0 | break; |
308 | 0 | } |
309 | |
|
310 | 0 | if ( !pSlot && _pParentPool ) |
311 | 0 | pSlot = _pParentPool->GetUnoSlot( rName ); |
312 | |
|
313 | 0 | return pSlot; |
314 | 0 | } |
315 | | |
316 | | SfxSlotPool& SfxSlotPool::GetSlotPool( SfxViewFrame *pFrame ) |
317 | 328k | { |
318 | 328k | SfxModule *pMod = SfxModule::GetActiveModule( pFrame ); |
319 | 328k | if ( pMod && pMod->GetSlotPool() ) |
320 | 8.02k | return *pMod->GetSlotPool(); |
321 | 320k | else |
322 | 320k | return *SfxGetpApp()->Get_Impl()->pSlotPool; |
323 | 328k | } |
324 | | |
325 | | |
326 | | /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |