ofz#44991 keep paragraph's that failed to load until import is complete
[LibreOffice.git] / sfx2 / source / control / msgpool.cxx
blobf7a94203e6b74c0657b853f3fd478591b01e0104
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
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>
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>
32 #include <sfx2/strings.hrc>
34 SfxSlotPool::SfxSlotPool(SfxSlotPool *pParent)
35 : _pParentPool( pParent )
36 , _nCurGroup(0)
37 , _nCurInterface(0)
38 , _nCurMsg(0)
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 )
49 delete pIF;
52 namespace
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)
61 return STR_GID_VIEW;
62 else if (nId == SfxGroupId::Document)
63 return STR_GID_DOCUMENT;
64 else if (nId == SfxGroupId::Edit)
65 return STR_GID_EDIT;
66 else if (nId == SfxGroupId::Macro)
67 return STR_GID_MACRO;
68 else if (nId == SfxGroupId::Options)
69 return STR_GID_OPTIONS;
70 else if (nId == SfxGroupId::Math)
71 return STR_GID_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)
81 return STR_GID_TEXT;
82 else if (nId == SfxGroupId::Frame)
83 return STR_GID_FRAME;
84 else if (nId == SfxGroupId::Graphic)
85 return STR_GID_GRAPHIC;
86 else if (nId == SfxGroupId::Table)
87 return STR_GID_TABLE;
88 else if (nId == SfxGroupId::Enumeration)
89 return STR_GID_ENUMERATION;
90 else if (nId == SfxGroupId::Data)
91 return STR_GID_DATA;
92 else if (nId == SfxGroupId::Special)
93 return STR_GID_SPECIAL;
94 else if (nId == SfxGroupId::Image)
95 return STR_GID_IMAGE;
96 else if (nId == SfxGroupId::Chart)
97 return STR_GID_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;
108 return {};
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 )
122 return;
124 // possibly add Interface-id and group-ids of funcs to the list of groups
125 if ( _pParentPool )
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());
139 else
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);
161 if ( pDef )
162 return pDef;
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() )
177 _nCurGroup = nNo;
178 if ( _pParentPool )
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;
184 else
186 // Otherwise search. If the group is not found in the parent
187 // pool, _nCurGroup is set outside the valid range
188 sal_uInt16 i;
189 for ( i=1; i<nParentCount; i++ )
190 if ( _vGroups[nNo] == _pParentPool->_vGroups[i] )
191 break;
192 _pParentPool->_nCurGroup = i;
196 TranslateId pResId = getGidResId(_vGroups[_nCurGroup]);
197 if (!pResId)
199 OSL_FAIL( "GroupId-Name not defined in SFX!" );
200 return OUString();
203 return SfxResId(pResId);
206 return OUString();
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;
240 ++_nCurInterface )
242 SfxInterface* pInterface = _vInterfaces[_nCurInterface-nFirstInterface];
243 for ( _nCurMsg = 0;
244 _nCurMsg < pInterface->Count();
245 ++_nCurMsg )
247 const SfxSlot& rMsg = pInterface->pSlots[_nCurMsg];
248 if (rMsg.GetGroupId() == _vGroups.at(_nCurGroup))
249 return &rMsg;
253 return nullptr;
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;
272 if ( pSlot )
273 return pSlot;
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() )
282 return nullptr;
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))
290 return &rMsg;
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 );
306 if ( pSlot )
307 break;
310 if ( !pSlot && _pParentPool )
311 pSlot = _pParentPool->GetUnoSlot( rName );
313 return pSlot;
316 SfxSlotPool& SfxSlotPool::GetSlotPool( SfxViewFrame *pFrame )
318 SfxModule *pMod = SfxModule::GetActiveModule( pFrame );
319 if ( pMod && pMod->GetSlotPool() )
320 return *pMod->GetSlotPool();
321 else
322 return *SfxGetpApp()->Get_Impl()->pSlotPool;
326 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */