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
<std::unique_ptr
<SfxObjectUI_Impl
>>
74 aObjectBars
; // registered ObjectBars
75 std::vector
<std::unique_ptr
<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 SfxObjectUI_Impl
* pUI
= CreateObjectBarUI_Impl(nPos
, nFlags
, eId
, nFeature
);
253 pImplData
->aObjectBars
.emplace_back(pUI
);
256 SfxObjectUI_Impl
* CreateObjectBarUI_Impl(sal_uInt16 nPos
, SfxVisibilityFlags nFlags
, ToolbarId eId
, SfxShellFeature nFeature
)
258 if (nFlags
== SfxVisibilityFlags::Invisible
)
259 nFlags
|= SfxVisibilityFlags::Standard
;
261 return new SfxObjectUI_Impl(nPos
, nFlags
, static_cast<sal_uInt32
>(eId
), nFeature
);
264 ToolbarId
SfxInterface::GetObjectBarId(sal_uInt16 nNo
) const
266 bool bGenoType
= (pGenoType
!= nullptr && pGenoType
->UseAsSuperClass());
269 // Are there toolbars in the super class?
270 sal_uInt16 nBaseCount
= pGenoType
->GetObjectBarCount();
271 if ( nNo
< nBaseCount
)
272 // The Super class comes first
273 return pGenoType
->GetObjectBarId(nNo
);
275 nNo
= nNo
- nBaseCount
;
278 assert( nNo
<pImplData
->aObjectBars
.size() );
280 return static_cast<ToolbarId
>(pImplData
->aObjectBars
[nNo
]->nObjId
);
283 sal_uInt16
SfxInterface::GetObjectBarPos( sal_uInt16 nNo
) const
285 bool bGenoType
= (pGenoType
!= nullptr && pGenoType
->UseAsSuperClass());
288 // Are there toolbars in the super class?
289 sal_uInt16 nBaseCount
= pGenoType
->GetObjectBarCount();
290 if ( nNo
< nBaseCount
)
291 // The Super class comes first
292 return pGenoType
->GetObjectBarPos( nNo
);
294 nNo
= nNo
- nBaseCount
;
297 assert( nNo
<pImplData
->aObjectBars
.size() );
299 return pImplData
->aObjectBars
[nNo
]->nPos
;
302 SfxVisibilityFlags
SfxInterface::GetObjectBarFlags( sal_uInt16 nNo
) const
304 bool bGenoType
= (pGenoType
!= nullptr && pGenoType
->UseAsSuperClass());
307 // Are there toolbars in the super class?
308 sal_uInt16 nBaseCount
= pGenoType
->GetObjectBarCount();
309 if ( nNo
< nBaseCount
)
310 // The Super class comes first
311 return pGenoType
->GetObjectBarFlags( nNo
);
313 nNo
= nNo
- nBaseCount
;
316 assert( nNo
<pImplData
->aObjectBars
.size() );
318 return pImplData
->aObjectBars
[nNo
]->nFlags
;
321 sal_uInt16
SfxInterface::GetObjectBarCount() const
323 if (pGenoType
&& pGenoType
->UseAsSuperClass())
324 return pImplData
->aObjectBars
.size() + pGenoType
->GetObjectBarCount();
326 return pImplData
->aObjectBars
.size();
329 void SfxInterface::RegisterChildWindow(sal_uInt16 nId
, bool bContext
)
331 RegisterChildWindow(nId
, bContext
, SfxShellFeature::NONE
);
334 void SfxInterface::RegisterChildWindow(sal_uInt16 nId
, bool bContext
, SfxShellFeature nFeature
)
336 SfxObjectUI_Impl
* pUI
= new SfxObjectUI_Impl(0, SfxVisibilityFlags::Invisible
, nId
, nFeature
);
337 pUI
->bContext
= bContext
;
338 pImplData
->aChildWindows
.emplace_back(pUI
);
341 void SfxInterface::RegisterStatusBar(StatusBarId eId
)
343 pImplData
->eStatBarResId
= eId
;
346 sal_uInt32
SfxInterface::GetChildWindowId (sal_uInt16 nNo
) const
350 // Are there ChildWindows in the superclass?
351 sal_uInt16 nBaseCount
= pGenoType
->GetChildWindowCount();
352 if ( nNo
< nBaseCount
)
353 // The Super class comes first
354 return pGenoType
->GetChildWindowId( nNo
);
356 nNo
= nNo
- nBaseCount
;
359 assert( nNo
<pImplData
->aChildWindows
.size() );
361 sal_uInt32 nRet
= pImplData
->aChildWindows
[nNo
]->nObjId
;
362 if ( pImplData
->aChildWindows
[nNo
]->bContext
)
363 nRet
+= sal_uInt16( nClassId
) << 16;
367 SfxShellFeature
SfxInterface::GetChildWindowFeature (sal_uInt16 nNo
) const
371 // Are there ChildWindows in the superclass?
372 sal_uInt16 nBaseCount
= pGenoType
->GetChildWindowCount();
373 if ( nNo
< nBaseCount
)
374 // The Super class comes first
375 return pGenoType
->GetChildWindowFeature( nNo
);
377 nNo
= nNo
- nBaseCount
;
380 assert( nNo
<pImplData
->aChildWindows
.size() );
382 return pImplData
->aChildWindows
[nNo
]->nFeature
;
386 sal_uInt16
SfxInterface::GetChildWindowCount() const
389 return pImplData
->aChildWindows
.size() + pGenoType
->GetChildWindowCount();
391 return pImplData
->aChildWindows
.size();
394 const OUString
& SfxInterface::GetPopupMenuName() const
396 return pImplData
->aPopupName
;
399 StatusBarId
SfxInterface::GetStatusBarId() const
401 if (pImplData
->eStatBarResId
== StatusBarId::None
&& pGenoType
)
402 return pGenoType
->GetStatusBarId();
404 return pImplData
->eStatBarResId
;
407 SfxShellFeature
SfxInterface::GetObjectBarFeature ( sal_uInt16 nNo
) const
409 bool bGenoType
= (pGenoType
!= nullptr && pGenoType
->UseAsSuperClass());
412 // Are there toolbars in the super class?
413 sal_uInt16 nBaseCount
= pGenoType
->GetObjectBarCount();
414 if ( nNo
< nBaseCount
)
415 // The Super class comes first
416 return pGenoType
->GetObjectBarFeature( nNo
);
418 nNo
= nNo
- nBaseCount
;
421 assert( nNo
<pImplData
->aObjectBars
.size() );
423 return pImplData
->aObjectBars
[nNo
]->nFeature
;
426 bool SfxInterface::IsObjectBarVisible(sal_uInt16 nNo
) const
428 bool bGenoType
= (pGenoType
!= nullptr && pGenoType
->UseAsSuperClass());
431 // Are there toolbars in the super class?
432 sal_uInt16 nBaseCount
= pGenoType
->GetObjectBarCount();
433 if ( nNo
< nBaseCount
)
434 // The Super class comes first
435 return pGenoType
->IsObjectBarVisible( nNo
);
437 nNo
= nNo
- nBaseCount
;
440 assert( nNo
<pImplData
->aObjectBars
.size() );
445 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */