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 .
23 #include <sal/log.hxx>
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>
34 SfxCompareSlots_qsort( const void* pSmaller
, const void* pBigger
)
36 return static_cast<int>(static_cast<SfxSlot
const *>(pSmaller
)->GetSlotId()) -
37 static_cast<int>(static_cast<SfxSlot
const *>(pBigger
)->GetSlotId());
41 SfxCompareSlots_bsearch( const void* pSmaller
, const void* pBigger
)
43 return static_cast<int>(*static_cast<sal_uInt16
const *>(pSmaller
)) -
44 static_cast<int>(static_cast<SfxSlot
const *>(pBigger
)->GetSlotId());
51 struct SfxObjectUI_Impl
54 SfxVisibilityFlags nFlags
;
57 SfxShellFeature nFeature
;
59 SfxObjectUI_Impl(sal_uInt16 n
, SfxVisibilityFlags f
, sal_uInt32 nId
, SfxShellFeature nFeat
) :
71 struct SfxInterface_Impl
73 std::vector
<SfxObjectUI_Impl
>
74 aObjectBars
; // registered ObjectBars
75 std::vector
<SfxObjectUI_Impl
>
76 aChildWindows
; // registered ChildWindows
77 OUString aPopupName
; // registered PopupMenu
78 StatusBarId eStatBarResId
; // registered StatusBar
81 : eStatBarResId(StatusBarId::None
)
86 static SfxObjectUI_Impl
CreateObjectBarUI_Impl(sal_uInt16 nPos
, SfxVisibilityFlags nFlags
, ToolbarId eId
, SfxShellFeature nFeature
);
88 // constructor, registers a new unit
89 SfxInterface::SfxInterface( const char *pClassName
,
90 bool bUsableSuperClass
,
92 const SfxInterface
* pParent
,
93 SfxSlot
&rSlotMap
, sal_uInt16 nSlotCount
):
97 bSuperClass(bUsableSuperClass
),
98 pImplData(new SfxInterface_Impl
)
100 SetSlotMap( rSlotMap
, nSlotCount
);
103 void SfxInterface::Register( const SfxModule
* pMod
)
106 pMod
->GetSlotPool()->RegisterInterface(*this);
108 SfxGetpApp()->GetAppSlotPool_Impl().RegisterInterface(*this);
111 void SfxInterface::SetSlotMap( SfxSlot
& rSlotMap
, sal_uInt16 nSlotCount
)
115 SfxSlot
* pIter
= pSlots
;
116 if ( 1 == nCount
&& !pIter
->pNextSlot
)
117 pIter
->pNextSlot
= pIter
;
119 if ( !pIter
->pNextSlot
)
121 // sort the SfxSlots by id
122 qsort( pSlots
, nCount
, sizeof(SfxSlot
), SfxCompareSlots_qsort
);
124 // link masters and slaves
125 sal_uInt16 nIter
= 1;
126 for ( pIter
= pSlots
; nIter
<= nCount
; ++pIter
, ++nIter
)
129 assert( nIter
== nCount
||
130 pIter
->GetSlotId() != (pIter
+1)->GetSlotId() );
132 if ( nullptr == pIter
->GetNextSlot() )
134 // Slots referring in circle to the next with the same
136 SfxSlot
*pLastSlot
= pIter
;
137 for ( sal_uInt16 n
= nIter
; n
< Count(); ++n
)
139 SfxSlot
*pCurSlot
= pSlots
+n
;
140 if ( pCurSlot
->GetStateFnc() == pIter
->GetStateFnc() )
142 pLastSlot
->pNextSlot
= pCurSlot
;
143 pLastSlot
= pCurSlot
;
146 pLastSlot
->pNextSlot
= pIter
;
153 sal_uInt16 nIter
= 1;
154 for ( SfxSlot
*pNext
= pIter
+1; nIter
< nCount
; ++pNext
, ++nIter
)
157 if ( pNext
->GetSlotId() <= pIter
->GetSlotId() )
158 SAL_WARN( "sfx.control", "Wrong order" );
160 const SfxSlot
*pCurSlot
= pIter
;
163 pCurSlot
= pCurSlot
->pNextSlot
;
164 if ( pCurSlot
->GetStateFnc() != pIter
->GetStateFnc() )
166 SAL_WARN("sfx.control", "Linked Slots with different State Methods : "
167 << pCurSlot
->GetSlotId()
168 << " , " << pIter
->GetSlotId() );
171 while ( pCurSlot
!= pIter
);
180 SfxInterface::~SfxInterface()
185 // searches for the specified func
187 const SfxSlot
* SfxInterface::GetSlot( sal_uInt16 nFuncId
) const
193 // find the id using binary search
194 void* p
= bsearch( &nFuncId
, pSlots
, nCount
, sizeof(SfxSlot
),
195 SfxCompareSlots_bsearch
);
196 if ( !p
&& pGenoType
)
197 return pGenoType
->GetSlot( nFuncId
);
199 return static_cast<const SfxSlot
*>(p
);
202 const SfxSlot
* SfxInterface::GetSlot( const OUString
& rCommand
) const
204 static const char UNO_COMMAND
[] = ".uno:";
206 OUString
aCommand( rCommand
);
207 if ( aCommand
.startsWith( UNO_COMMAND
) )
208 aCommand
= aCommand
.copy( sizeof( UNO_COMMAND
)-1 );
210 for ( sal_uInt16 n
=0; n
<nCount
; n
++ )
212 if ( (pSlots
+n
)->pUnoName
&&
213 aCommand
.compareToIgnoreAsciiCaseAscii( (pSlots
+n
)->GetUnoName() ) == 0 )
217 return pGenoType
? pGenoType
->GetSlot( aCommand
) : nullptr;
221 const SfxSlot
* SfxInterface::GetRealSlot( const SfxSlot
*pSlot
) const
227 if ( !ContainsSlot_Impl(pSlot
) )
230 return pGenoType
->GetRealSlot(pSlot
);
231 SAL_WARN( "sfx.control", "unknown Slot" );
239 void SfxInterface::RegisterPopupMenu( const OUString
& rResourceName
)
241 pImplData
->aPopupName
= rResourceName
;
244 void SfxInterface::RegisterObjectBar(sal_uInt16 nPos
, SfxVisibilityFlags nFlags
, ToolbarId eId
)
246 RegisterObjectBar(nPos
, nFlags
, eId
, SfxShellFeature::NONE
);
249 void SfxInterface::RegisterObjectBar(sal_uInt16 nPos
, SfxVisibilityFlags nFlags
, ToolbarId eId
, SfxShellFeature nFeature
)
251 pImplData
->aObjectBars
.emplace_back( CreateObjectBarUI_Impl(nPos
, nFlags
, eId
, nFeature
) );
254 SfxObjectUI_Impl
CreateObjectBarUI_Impl(sal_uInt16 nPos
, SfxVisibilityFlags nFlags
, ToolbarId eId
, SfxShellFeature nFeature
)
256 if (nFlags
== SfxVisibilityFlags::Invisible
)
257 nFlags
|= SfxVisibilityFlags::Standard
;
259 return SfxObjectUI_Impl(nPos
, nFlags
, static_cast<sal_uInt32
>(eId
), nFeature
);
262 ToolbarId
SfxInterface::GetObjectBarId(sal_uInt16 nNo
) const
264 bool bGenoType
= (pGenoType
!= nullptr && pGenoType
->UseAsSuperClass());
267 // Are there toolbars in the super class?
268 sal_uInt16 nBaseCount
= pGenoType
->GetObjectBarCount();
269 if ( nNo
< nBaseCount
)
270 // The Super class comes first
271 return pGenoType
->GetObjectBarId(nNo
);
273 nNo
= nNo
- nBaseCount
;
276 assert( nNo
<pImplData
->aObjectBars
.size() );
278 return static_cast<ToolbarId
>(pImplData
->aObjectBars
[nNo
].nObjId
);
281 sal_uInt16
SfxInterface::GetObjectBarPos( sal_uInt16 nNo
) const
283 bool bGenoType
= (pGenoType
!= nullptr && pGenoType
->UseAsSuperClass());
286 // Are there toolbars in the super class?
287 sal_uInt16 nBaseCount
= pGenoType
->GetObjectBarCount();
288 if ( nNo
< nBaseCount
)
289 // The Super class comes first
290 return pGenoType
->GetObjectBarPos( nNo
);
292 nNo
= nNo
- nBaseCount
;
295 assert( nNo
<pImplData
->aObjectBars
.size() );
297 return pImplData
->aObjectBars
[nNo
].nPos
;
300 SfxVisibilityFlags
SfxInterface::GetObjectBarFlags( sal_uInt16 nNo
) const
302 bool bGenoType
= (pGenoType
!= nullptr && pGenoType
->UseAsSuperClass());
305 // Are there toolbars in the super class?
306 sal_uInt16 nBaseCount
= pGenoType
->GetObjectBarCount();
307 if ( nNo
< nBaseCount
)
308 // The Super class comes first
309 return pGenoType
->GetObjectBarFlags( nNo
);
311 nNo
= nNo
- nBaseCount
;
314 assert( nNo
<pImplData
->aObjectBars
.size() );
316 return pImplData
->aObjectBars
[nNo
].nFlags
;
319 sal_uInt16
SfxInterface::GetObjectBarCount() const
321 if (pGenoType
&& pGenoType
->UseAsSuperClass())
322 return pImplData
->aObjectBars
.size() + pGenoType
->GetObjectBarCount();
324 return pImplData
->aObjectBars
.size();
327 void SfxInterface::RegisterChildWindow(sal_uInt16 nId
, bool bContext
)
329 RegisterChildWindow(nId
, bContext
, SfxShellFeature::NONE
);
332 void SfxInterface::RegisterChildWindow(sal_uInt16 nId
, bool bContext
, SfxShellFeature nFeature
)
334 SfxObjectUI_Impl
aUI(0, SfxVisibilityFlags::Invisible
, nId
, nFeature
);
335 aUI
.bContext
= bContext
;
336 pImplData
->aChildWindows
.emplace_back(aUI
);
339 void SfxInterface::RegisterStatusBar(StatusBarId eId
)
341 pImplData
->eStatBarResId
= eId
;
344 sal_uInt32
SfxInterface::GetChildWindowId (sal_uInt16 nNo
) const
348 // Are there ChildWindows in the superclass?
349 sal_uInt16 nBaseCount
= pGenoType
->GetChildWindowCount();
350 if ( nNo
< nBaseCount
)
351 // The Super class comes first
352 return pGenoType
->GetChildWindowId( nNo
);
354 nNo
= nNo
- nBaseCount
;
357 assert( nNo
<pImplData
->aChildWindows
.size() );
359 sal_uInt32 nRet
= pImplData
->aChildWindows
[nNo
].nObjId
;
360 if ( pImplData
->aChildWindows
[nNo
].bContext
)
361 nRet
+= sal_uInt16( nClassId
) << 16;
365 SfxShellFeature
SfxInterface::GetChildWindowFeature (sal_uInt16 nNo
) const
369 // Are there ChildWindows in the superclass?
370 sal_uInt16 nBaseCount
= pGenoType
->GetChildWindowCount();
371 if ( nNo
< nBaseCount
)
372 // The Super class comes first
373 return pGenoType
->GetChildWindowFeature( nNo
);
375 nNo
= nNo
- nBaseCount
;
378 assert( nNo
<pImplData
->aChildWindows
.size() );
380 return pImplData
->aChildWindows
[nNo
].nFeature
;
384 sal_uInt16
SfxInterface::GetChildWindowCount() const
387 return pImplData
->aChildWindows
.size() + pGenoType
->GetChildWindowCount();
389 return pImplData
->aChildWindows
.size();
392 const OUString
& SfxInterface::GetPopupMenuName() const
394 return pImplData
->aPopupName
;
397 StatusBarId
SfxInterface::GetStatusBarId() const
399 if (pImplData
->eStatBarResId
== StatusBarId::None
&& pGenoType
)
400 return pGenoType
->GetStatusBarId();
402 return pImplData
->eStatBarResId
;
405 SfxShellFeature
SfxInterface::GetObjectBarFeature ( sal_uInt16 nNo
) const
407 bool bGenoType
= (pGenoType
!= nullptr && pGenoType
->UseAsSuperClass());
410 // Are there toolbars in the super class?
411 sal_uInt16 nBaseCount
= pGenoType
->GetObjectBarCount();
412 if ( nNo
< nBaseCount
)
413 // The Super class comes first
414 return pGenoType
->GetObjectBarFeature( nNo
);
416 nNo
= nNo
- nBaseCount
;
419 assert( nNo
<pImplData
->aObjectBars
.size() );
421 return pImplData
->aObjectBars
[nNo
].nFeature
;
424 bool SfxInterface::IsObjectBarVisible(sal_uInt16 nNo
) const
426 bool bGenoType
= (pGenoType
!= nullptr && pGenoType
->UseAsSuperClass());
429 // Are there toolbars in the super class?
430 sal_uInt16 nBaseCount
= pGenoType
->GetObjectBarCount();
431 if ( nNo
< nBaseCount
)
432 // The Super class comes first
433 return pGenoType
->IsObjectBarVisible( nNo
);
435 nNo
= nNo
- nBaseCount
;
438 assert( nNo
<pImplData
->aObjectBars
.size() );
443 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */