/src/libreoffice/sfx2/source/control/objface.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 <assert.h> |
21 | | #include <stdlib.h> |
22 | | |
23 | | #include <sal/log.hxx> |
24 | | |
25 | | #include <sfx2/module.hxx> |
26 | | #include <sfx2/objface.hxx> |
27 | | #include <sfx2/msg.hxx> |
28 | | #include <sfx2/app.hxx> |
29 | | #include <sfx2/msgpool.hxx> |
30 | | |
31 | | extern "C" { |
32 | | |
33 | | |
34 | | static int |
35 | | SfxCompareSlots_bsearch( const void* pSmaller, const void* pBigger ) |
36 | 76.2M | { |
37 | 76.2M | return static_cast<int>(*static_cast<sal_uInt16 const *>(pSmaller)) - |
38 | 76.2M | static_cast<int>(static_cast<SfxSlot const *>(pBigger)->GetSlotId()); |
39 | 76.2M | } |
40 | | |
41 | | } |
42 | | |
43 | | namespace { |
44 | | |
45 | | struct SfxObjectUI_Impl |
46 | | { |
47 | | sal_uInt16 nPos; |
48 | | SfxVisibilityFlags nFlags; |
49 | | sal_uInt32 nObjId; |
50 | | bool bContext; |
51 | | SfxShellFeature nFeature; |
52 | | |
53 | | SfxObjectUI_Impl(sal_uInt16 n, SfxVisibilityFlags f, sal_uInt32 nId, SfxShellFeature nFeat) : |
54 | 1.99k | nPos(n), |
55 | 1.99k | nFlags(f), |
56 | 1.99k | nObjId(nId), |
57 | 1.99k | bContext(false), |
58 | 1.99k | nFeature(nFeat) |
59 | 1.99k | { |
60 | 1.99k | } |
61 | | }; |
62 | | |
63 | | } |
64 | | |
65 | | struct SfxInterface_Impl |
66 | | { |
67 | | std::vector<SfxObjectUI_Impl> |
68 | | aObjectBars; // registered ObjectBars |
69 | | std::vector<SfxObjectUI_Impl> |
70 | | aChildWindows; // registered ChildWindows |
71 | | OUString aPopupName; // registered PopupMenu |
72 | | StatusBarId eStatBarResId; // registered StatusBar |
73 | | |
74 | | SfxInterface_Impl() |
75 | 725 | : eStatBarResId(StatusBarId::None) |
76 | 725 | { |
77 | 725 | } |
78 | | }; |
79 | | |
80 | | static SfxObjectUI_Impl CreateObjectBarUI_Impl(sal_uInt16 nPos, SfxVisibilityFlags nFlags, ToolbarId eId, SfxShellFeature nFeature); |
81 | | |
82 | | // constructor, registers a new unit |
83 | | SfxInterface::SfxInterface( const char *pClassName, |
84 | | bool bUsableSuperClass, |
85 | | SfxInterfaceId nId, |
86 | | const SfxInterface* pParent, |
87 | | const SfxSlot &rSlotMap, sal_uInt16 nSlotCount ): |
88 | 725 | pName(pClassName), |
89 | 725 | pGenoType(pParent), |
90 | 725 | nClassId(nId), |
91 | 725 | bSuperClass(bUsableSuperClass), |
92 | 725 | pImplData(new SfxInterface_Impl) |
93 | 725 | { |
94 | 725 | SetSlotMap( rSlotMap, nSlotCount ); |
95 | 725 | } |
96 | | |
97 | | void SfxInterface::Register( const SfxModule* pMod ) |
98 | 725 | { |
99 | 725 | if ( pMod ) |
100 | 564 | pMod->GetSlotPool()->RegisterInterface(*this); |
101 | 161 | else |
102 | 161 | SfxGetpApp()->GetAppSlotPool_Impl().RegisterInterface(*this); |
103 | 725 | } |
104 | | |
105 | | void SfxInterface::SetSlotMap( const SfxSlot& rSlotMap, sal_uInt16 nSlotCount ) |
106 | 725 | { |
107 | 725 | pSlots = &rSlotMap; |
108 | 725 | nCount = nSlotCount; |
109 | 725 | const SfxSlot* pIter = pSlots; |
110 | | |
111 | 725 | if ( !pIter->pNextSlot ) |
112 | 89 | { |
113 | 89 | assert(std::is_sorted(pSlots, pSlots + nCount, |
114 | 89 | [](const SfxSlot& rLHS, const SfxSlot& rRHS) |
115 | 89 | { |
116 | 89 | return rLHS.GetSlotId() < rRHS.GetSlotId(); |
117 | 89 | })); |
118 | 89 | } |
119 | | #ifdef DBG_UTIL |
120 | | else |
121 | | { |
122 | | sal_uInt16 nIter = 1; |
123 | | for (const SfxSlot *pNext = pIter+1; nIter < nCount; ++pNext, ++nIter) |
124 | | { |
125 | | |
126 | | if ( pNext->GetSlotId() <= pIter->GetSlotId() ) |
127 | | SAL_WARN( "sfx.control", "Wrong order" ); |
128 | | |
129 | | const SfxSlot *pCurSlot = pIter; |
130 | | do |
131 | | { |
132 | | pCurSlot = pCurSlot->pNextSlot; |
133 | | if ( pCurSlot->GetStateFnc() != pIter->GetStateFnc() ) |
134 | | { |
135 | | SAL_WARN("sfx.control", "Linked Slots with different State Methods : " |
136 | | << pCurSlot->GetSlotId() |
137 | | << " , " << pIter->GetSlotId() ); |
138 | | } |
139 | | } |
140 | | while ( pCurSlot != pIter ); |
141 | | |
142 | | pIter = pNext; |
143 | | } |
144 | | } |
145 | | #endif |
146 | 725 | } |
147 | | |
148 | | |
149 | | SfxInterface::~SfxInterface() |
150 | 0 | { |
151 | 0 | } |
152 | | |
153 | | |
154 | | // searches for the specified func |
155 | | |
156 | | const SfxSlot* SfxInterface::GetSlot( sal_uInt16 nFuncId ) const |
157 | 15.5M | { |
158 | | |
159 | 15.5M | assert( pSlots ); |
160 | 15.5M | assert( nCount ); |
161 | | |
162 | | // find the id using binary search |
163 | 15.5M | void* p = bsearch( &nFuncId, pSlots, nCount, sizeof(SfxSlot), |
164 | 15.5M | SfxCompareSlots_bsearch ); |
165 | 15.5M | if ( !p && pGenoType ) |
166 | 8.18M | return pGenoType->GetSlot( nFuncId ); |
167 | | |
168 | 7.34M | return static_cast<const SfxSlot*>(p); |
169 | 15.5M | } |
170 | | |
171 | | const SfxSlot* SfxInterface::GetSlot( const OUString& rCommand ) const |
172 | 0 | { |
173 | 0 | static const char UNO_COMMAND[] = ".uno:"; |
174 | |
|
175 | 0 | OUString aCommand( rCommand ); |
176 | 0 | if ( aCommand.startsWith( UNO_COMMAND ) ) |
177 | 0 | aCommand = aCommand.copy( sizeof( UNO_COMMAND )-1 ); |
178 | |
|
179 | 0 | for ( sal_uInt16 n=0; n<nCount; n++ ) |
180 | 0 | { |
181 | 0 | if ( aCommand.equalsIgnoreAsciiCase( (pSlots+n)->GetUnoName() ) ) |
182 | 0 | return pSlots+n; |
183 | 0 | } |
184 | | |
185 | 0 | return pGenoType ? pGenoType->GetSlot( aCommand ) : nullptr; |
186 | 0 | } |
187 | | |
188 | | |
189 | | const SfxSlot* SfxInterface::GetRealSlot( const SfxSlot *pSlot ) const |
190 | 0 | { |
191 | |
|
192 | 0 | assert( pSlots ); |
193 | 0 | assert( nCount ); |
194 | |
|
195 | 0 | if ( !ContainsSlot_Impl(pSlot) ) |
196 | 0 | { |
197 | 0 | if(pGenoType) |
198 | 0 | return pGenoType->GetRealSlot(pSlot); |
199 | 0 | SAL_WARN( "sfx.control", "unknown Slot" ); |
200 | 0 | return nullptr; |
201 | 0 | } |
202 | | |
203 | 0 | return nullptr; |
204 | 0 | } |
205 | | |
206 | | |
207 | | void SfxInterface::RegisterPopupMenu( const OUString& rResourceName ) |
208 | 344 | { |
209 | 344 | pImplData->aPopupName = rResourceName; |
210 | 344 | } |
211 | | |
212 | | void SfxInterface::RegisterObjectBar(sal_uInt16 nPos, SfxVisibilityFlags nFlags, ToolbarId eId) |
213 | 385 | { |
214 | 385 | RegisterObjectBar(nPos, nFlags, eId, SfxShellFeature::NONE); |
215 | 385 | } |
216 | | |
217 | | void SfxInterface::RegisterObjectBar(sal_uInt16 nPos, SfxVisibilityFlags nFlags, ToolbarId eId, SfxShellFeature nFeature) |
218 | 515 | { |
219 | 515 | pImplData->aObjectBars.emplace_back( CreateObjectBarUI_Impl(nPos, nFlags, eId, nFeature) ); |
220 | 515 | } |
221 | | |
222 | | SfxObjectUI_Impl CreateObjectBarUI_Impl(sal_uInt16 nPos, SfxVisibilityFlags nFlags, ToolbarId eId, SfxShellFeature nFeature) |
223 | 515 | { |
224 | 515 | if (nFlags == SfxVisibilityFlags::Invisible) |
225 | 182 | nFlags |= SfxVisibilityFlags::Standard; |
226 | | |
227 | 515 | return SfxObjectUI_Impl(nPos, nFlags, static_cast<sal_uInt32>(eId), nFeature); |
228 | 515 | } |
229 | | |
230 | | ToolbarId SfxInterface::GetObjectBarId(sal_uInt16 nNo) const |
231 | 21.3k | { |
232 | 21.3k | bool bGenoType = (pGenoType != nullptr && pGenoType->UseAsSuperClass()); |
233 | 21.3k | if ( bGenoType ) |
234 | 12.8k | { |
235 | | // Are there toolbars in the super class? |
236 | 12.8k | sal_uInt16 nBaseCount = pGenoType->GetObjectBarCount(); |
237 | 12.8k | if ( nNo < nBaseCount ) |
238 | | // The Super class comes first |
239 | 0 | return pGenoType->GetObjectBarId(nNo); |
240 | 12.8k | else |
241 | 12.8k | nNo = nNo - nBaseCount; |
242 | 12.8k | } |
243 | | |
244 | 21.3k | assert( nNo<pImplData->aObjectBars.size() ); |
245 | | |
246 | 21.3k | return static_cast<ToolbarId>(pImplData->aObjectBars[nNo].nObjId); |
247 | 21.3k | } |
248 | | |
249 | | sal_uInt16 SfxInterface::GetObjectBarPos( sal_uInt16 nNo ) const |
250 | 42.6k | { |
251 | 42.6k | bool bGenoType = (pGenoType != nullptr && pGenoType->UseAsSuperClass()); |
252 | 42.6k | if ( bGenoType ) |
253 | 21.3k | { |
254 | | // Are there toolbars in the super class? |
255 | 21.3k | sal_uInt16 nBaseCount = pGenoType->GetObjectBarCount(); |
256 | 21.3k | if ( nNo < nBaseCount ) |
257 | | // The Super class comes first |
258 | 0 | return pGenoType->GetObjectBarPos( nNo ); |
259 | 21.3k | else |
260 | 21.3k | nNo = nNo - nBaseCount; |
261 | 21.3k | } |
262 | | |
263 | 42.6k | assert( nNo<pImplData->aObjectBars.size() ); |
264 | | |
265 | 42.6k | return pImplData->aObjectBars[nNo].nPos; |
266 | 42.6k | } |
267 | | |
268 | | SfxVisibilityFlags SfxInterface::GetObjectBarFlags( sal_uInt16 nNo ) const |
269 | 42.6k | { |
270 | 42.6k | bool bGenoType = (pGenoType != nullptr && pGenoType->UseAsSuperClass()); |
271 | 42.6k | if ( bGenoType ) |
272 | 21.3k | { |
273 | | // Are there toolbars in the super class? |
274 | 21.3k | sal_uInt16 nBaseCount = pGenoType->GetObjectBarCount(); |
275 | 21.3k | if ( nNo < nBaseCount ) |
276 | | // The Super class comes first |
277 | 0 | return pGenoType->GetObjectBarFlags( nNo ); |
278 | 21.3k | else |
279 | 21.3k | nNo = nNo - nBaseCount; |
280 | 21.3k | } |
281 | | |
282 | 42.6k | assert( nNo<pImplData->aObjectBars.size() ); |
283 | | |
284 | 42.6k | return pImplData->aObjectBars[nNo].nFlags; |
285 | 42.6k | } |
286 | | |
287 | | sal_uInt16 SfxInterface::GetObjectBarCount() const |
288 | 243k | { |
289 | 243k | if (pGenoType && pGenoType->UseAsSuperClass()) |
290 | 55.4k | return pImplData->aObjectBars.size() + pGenoType->GetObjectBarCount(); |
291 | 187k | else |
292 | 187k | return pImplData->aObjectBars.size(); |
293 | 243k | } |
294 | | |
295 | | void SfxInterface::RegisterChildWindow(sal_uInt16 nId, bool bContext) |
296 | 1.33k | { |
297 | 1.33k | RegisterChildWindow(nId, bContext, SfxShellFeature::NONE); |
298 | 1.33k | } |
299 | | |
300 | | void SfxInterface::RegisterChildWindow(sal_uInt16 nId, bool bContext, SfxShellFeature nFeature) |
301 | 1.47k | { |
302 | 1.47k | SfxObjectUI_Impl aUI(0, SfxVisibilityFlags::Invisible, nId, nFeature); |
303 | 1.47k | aUI.bContext = bContext; |
304 | 1.47k | pImplData->aChildWindows.emplace_back(aUI); |
305 | 1.47k | } |
306 | | |
307 | | void SfxInterface::RegisterStatusBar(StatusBarId eId) |
308 | 54 | { |
309 | 54 | pImplData->eStatBarResId = eId; |
310 | 54 | } |
311 | | |
312 | | sal_uInt32 SfxInterface::GetChildWindowId (sal_uInt16 nNo) const |
313 | 302k | { |
314 | 302k | if ( pGenoType ) |
315 | 153k | { |
316 | | // Are there ChildWindows in the superclass? |
317 | 153k | sal_uInt16 nBaseCount = pGenoType->GetChildWindowCount(); |
318 | 153k | if ( nNo < nBaseCount ) |
319 | | // The Super class comes first |
320 | 25.6k | return pGenoType->GetChildWindowId( nNo ); |
321 | 127k | else |
322 | 127k | nNo = nNo - nBaseCount; |
323 | 153k | } |
324 | | |
325 | 302k | assert( nNo<pImplData->aChildWindows.size() ); |
326 | | |
327 | 277k | sal_uInt32 nRet = pImplData->aChildWindows[nNo].nObjId; |
328 | 277k | if ( pImplData->aChildWindows[nNo].bContext ) |
329 | 8.52k | nRet += sal_uInt16( nClassId ) << 16; |
330 | 277k | return nRet; |
331 | 302k | } |
332 | | |
333 | | SfxShellFeature SfxInterface::GetChildWindowFeature (sal_uInt16 nNo) const |
334 | 302k | { |
335 | 302k | if ( pGenoType ) |
336 | 153k | { |
337 | | // Are there ChildWindows in the superclass? |
338 | 153k | sal_uInt16 nBaseCount = pGenoType->GetChildWindowCount(); |
339 | 153k | if ( nNo < nBaseCount ) |
340 | | // The Super class comes first |
341 | 25.6k | return pGenoType->GetChildWindowFeature( nNo ); |
342 | 127k | else |
343 | 127k | nNo = nNo - nBaseCount; |
344 | 153k | } |
345 | | |
346 | 302k | assert( nNo<pImplData->aChildWindows.size() ); |
347 | | |
348 | 277k | return pImplData->aChildWindows[nNo].nFeature; |
349 | 302k | } |
350 | | |
351 | | |
352 | | sal_uInt16 SfxInterface::GetChildWindowCount() const |
353 | 827k | { |
354 | 827k | if (pGenoType) |
355 | 187k | return pImplData->aChildWindows.size() + pGenoType->GetChildWindowCount(); |
356 | 639k | else |
357 | 639k | return pImplData->aChildWindows.size(); |
358 | 827k | } |
359 | | |
360 | | const OUString& SfxInterface::GetPopupMenuName() const |
361 | 0 | { |
362 | 0 | return pImplData->aPopupName; |
363 | 0 | } |
364 | | |
365 | | StatusBarId SfxInterface::GetStatusBarId() const |
366 | 81.0k | { |
367 | 81.0k | if (pImplData->eStatBarResId == StatusBarId::None && pGenoType) |
368 | 25.5k | return pGenoType->GetStatusBarId(); |
369 | 55.4k | else |
370 | 55.4k | return pImplData->eStatBarResId; |
371 | 81.0k | } |
372 | | |
373 | | SfxShellFeature SfxInterface::GetObjectBarFeature ( sal_uInt16 nNo ) const |
374 | 42.6k | { |
375 | 42.6k | bool bGenoType = (pGenoType != nullptr && pGenoType->UseAsSuperClass()); |
376 | 42.6k | if ( bGenoType ) |
377 | 21.3k | { |
378 | | // Are there toolbars in the super class? |
379 | 21.3k | sal_uInt16 nBaseCount = pGenoType->GetObjectBarCount(); |
380 | 21.3k | if ( nNo < nBaseCount ) |
381 | | // The Super class comes first |
382 | 0 | return pGenoType->GetObjectBarFeature( nNo ); |
383 | 21.3k | else |
384 | 21.3k | nNo = nNo - nBaseCount; |
385 | 21.3k | } |
386 | | |
387 | 42.6k | assert( nNo<pImplData->aObjectBars.size() ); |
388 | | |
389 | 42.6k | return pImplData->aObjectBars[nNo].nFeature; |
390 | 42.6k | } |
391 | | |
392 | | bool SfxInterface::IsObjectBarVisible(sal_uInt16 nNo) const |
393 | 21.3k | { |
394 | 21.3k | bool bGenoType = (pGenoType != nullptr && pGenoType->UseAsSuperClass()); |
395 | 21.3k | if ( bGenoType ) |
396 | 12.8k | { |
397 | | // Are there toolbars in the super class? |
398 | 12.8k | sal_uInt16 nBaseCount = pGenoType->GetObjectBarCount(); |
399 | 12.8k | if ( nNo < nBaseCount ) |
400 | | // The Super class comes first |
401 | 0 | return pGenoType->IsObjectBarVisible( nNo ); |
402 | 12.8k | else |
403 | 12.8k | nNo = nNo - nBaseCount; |
404 | 12.8k | } |
405 | | |
406 | 21.3k | assert( nNo<pImplData->aObjectBars.size() ); |
407 | | |
408 | 21.3k | return true; |
409 | 21.3k | } |
410 | | |
411 | | /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |