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 <tools/rcid.h>
26 #include <tools/stream.hxx>
27 #include "tools/resmgr.hxx"
29 #include <sfx2/module.hxx>
30 #include <sfx2/objface.hxx>
31 #include <sfx2/msg.hxx>
32 #include <sfx2/app.hxx>
33 #include <sfx2/msgpool.hxx>
34 #include <sfx2/sfxresid.hxx>
35 #include <sfx2/objsh.hxx>
36 #include <rtl/strbuf.hxx>
41 SfxCompareSlots_qsort( const void* pSmaller
, const void* pBigger
)
43 return ( (int) static_cast<SfxSlot
const *>(pSmaller
)->GetSlotId() ) -
44 ( (int) static_cast<SfxSlot
const *>(pBigger
)->GetSlotId() );
48 SfxCompareSlots_bsearch( const void* pSmaller
, const void* pBigger
)
50 return ( (int) *static_cast<sal_uInt16
const *>(pSmaller
) ) -
51 ( (int) static_cast<SfxSlot
const *>(pBigger
)->GetSlotId() );
56 struct SfxObjectUI_Impl
64 SfxObjectUI_Impl(sal_uInt16 n
, sal_uInt32 nId
, bool bVis
, sal_uInt32 nFeat
) :
74 typedef std::vector
<SfxObjectUI_Impl
*> SfxObjectUIArr_Impl
;
76 struct SfxInterface_Impl
78 SfxObjectUIArr_Impl aObjectBars
; // registered ObjectBars
79 SfxObjectUIArr_Impl aChildWindows
; // registered ChildWindows
80 ResId aPopupRes
; // registered PopupMenu
81 ResId aStatBarRes
; // registered StatusBar
86 aPopupRes(nullptr, *SfxApplication::GetSfxResManager()),
87 aStatBarRes(nullptr, *SfxApplication::GetSfxResManager())
95 for (SfxObjectUIArr_Impl::const_iterator it
= aObjectBars
.begin(); it
!= aObjectBars
.end(); ++it
)
98 for (SfxObjectUIArr_Impl::const_iterator it
= aChildWindows
.begin(); it
!= aChildWindows
.end(); ++it
)
103 static SfxObjectUI_Impl
* CreateObjectBarUI_Impl(sal_uInt16 nPos
, sal_uInt32 nResId
, sal_uInt32 nFeature
);
105 // constuctor, registeres a new unit
106 SfxInterface::SfxInterface( const char *pClassName
,
107 bool bUsableSuperClass
,
109 const SfxInterface
* pParent
,
110 SfxSlot
&rSlotMap
, sal_uInt16 nSlotCount
):
114 bSuperClass(bUsableSuperClass
),
117 pImpData
= new SfxInterface_Impl
;
118 SetSlotMap( rSlotMap
, nSlotCount
);
121 void SfxInterface::Register( SfxModule
* pMod
)
123 pImpData
->bRegistered
= true;
124 pImpData
->pModule
= pMod
;
126 pMod
->GetSlotPool()->RegisterInterface(*this);
128 SfxGetpApp()->GetAppSlotPool_Impl().RegisterInterface(*this);
131 void SfxInterface::SetSlotMap( SfxSlot
& rSlotMap
, sal_uInt16 nSlotCount
)
135 SfxSlot
* pIter
= pSlots
;
136 if ( 1 == nCount
&& !pIter
->pNextSlot
)
137 pIter
->pNextSlot
= pIter
;
139 if ( !pIter
->pNextSlot
)
141 // sort the SfxSlots by id
142 qsort( pSlots
, nCount
, sizeof(SfxSlot
), SfxCompareSlots_qsort
);
144 // link masters and slaves
145 sal_uInt16 nIter
= 1;
146 for ( pIter
= pSlots
; nIter
<= nCount
; ++pIter
, ++nIter
)
149 assert( nIter
== nCount
||
150 pIter
->GetSlotId() != (pIter
+1)->GetSlotId() );
152 // every master refers to his first slave (ENUM),
153 // all slaves refer to their master.
154 // Slaves refer in a circle to the other slaves with the same master
155 if ( pIter
->GetKind() == SFX_KIND_ENUM
)
157 pIter
->pLinkedSlot
= GetSlot( pIter
->nMasterSlotId
);
158 assert( pIter
->pLinkedSlot
);
159 if ( !pIter
->pLinkedSlot
->pLinkedSlot
)
160 const_cast<SfxSlot
*>(pIter
->pLinkedSlot
)->pLinkedSlot
= pIter
;
162 if ( 0 == pIter
->GetNextSlot() )
164 SfxSlot
*pLastSlot
= pIter
;
165 for ( sal_uInt16 n
= nIter
; n
< Count(); ++n
)
167 SfxSlot
*pCurSlot
= (pSlots
+n
);
168 if ( pCurSlot
->nMasterSlotId
== pIter
->nMasterSlotId
)
170 pLastSlot
->pNextSlot
= pCurSlot
;
171 pLastSlot
= pCurSlot
;
174 pLastSlot
->pNextSlot
= pIter
;
177 else if ( 0 == pIter
->GetNextSlot() )
179 // Slots referring in circle to the next with the same
181 SfxSlot
*pLastSlot
= pIter
;
182 for ( sal_uInt16 n
= nIter
; n
< Count(); ++n
)
184 SfxSlot
*pCurSlot
= (pSlots
+n
);
185 if ( pCurSlot
->GetStateFnc() == pIter
->GetStateFnc() )
187 pLastSlot
->pNextSlot
= pCurSlot
;
188 pLastSlot
= pCurSlot
;
191 pLastSlot
->pNextSlot
= pIter
;
198 sal_uInt16 nIter
= 1;
199 for ( SfxSlot
*pNext
= pIter
+1; nIter
< nCount
; ++pNext
, ++nIter
)
202 if ( pNext
->GetSlotId() <= pIter
->GetSlotId() )
203 SAL_WARN( "sfx.control", "Wrong order" );
205 if ( pIter
->GetKind() == SFX_KIND_ENUM
)
207 const SfxSlot
*pMasterSlot
= GetSlot(pIter
->nMasterSlotId
);
208 const SfxSlot
*pFirstSlave
= pMasterSlot
->pLinkedSlot
;
209 const SfxSlot
*pSlave
= pFirstSlave
;
212 if ( pSlave
->pLinkedSlot
!= pMasterSlot
)
214 OStringBuffer
aStr("Wrong Master/Slave- link: ");
215 aStr
.append(static_cast<sal_Int32
>(
216 pMasterSlot
->GetSlotId()));
218 aStr
.append(static_cast<sal_Int32
>(
219 pSlave
->GetSlotId()));
220 SAL_WARN("sfx.control", aStr
.getStr());
223 if ( pSlave
->nMasterSlotId
!= pMasterSlot
->GetSlotId() )
225 OStringBuffer
aStr("Wrong Master/Slave-Ids: ");
226 aStr
.append(static_cast<sal_Int32
>(
227 pMasterSlot
->GetSlotId()));
229 aStr
.append(static_cast<sal_Int32
>(
230 pSlave
->GetSlotId()));
231 SAL_WARN("sfx.control", aStr
.getStr());
234 pSlave
= pSlave
->pNextSlot
;
236 while ( pSlave
!= pFirstSlave
);
240 if ( pIter
->pLinkedSlot
)
242 if ( pIter
->pLinkedSlot
->GetKind() != SFX_KIND_ENUM
)
244 OStringBuffer
aStr("Slave is no enum: ");
245 aStr
.append(static_cast<sal_Int32
>(pIter
->GetSlotId()));
247 aStr
.append(static_cast<sal_Int32
>(
248 pIter
->pLinkedSlot
->GetSlotId()));
249 SAL_WARN("sfx.control", aStr
.getStr());
253 const SfxSlot
*pCurSlot
= pIter
;
256 pCurSlot
= pCurSlot
->pNextSlot
;
257 if ( pCurSlot
->GetStateFnc() != pIter
->GetStateFnc() )
259 OStringBuffer
aStr("Linked Slots with different State Methods : ");
260 aStr
.append(static_cast<sal_Int32
>(
261 pCurSlot
->GetSlotId()));
263 aStr
.append(static_cast<sal_Int32
>(pIter
->GetSlotId()));
264 SAL_WARN("sfx.control", aStr
.getStr());
267 while ( pCurSlot
!= pIter
);
278 SfxInterface::~SfxInterface()
280 SfxModule
*pMod
= pImpData
->pModule
;
281 bool bRegistered
= pImpData
->bRegistered
;
283 assert( bRegistered
);
287 pMod
->GetSlotPool()->ReleaseInterface(*this);
289 SfxGetpApp()->GetAppSlotPool_Impl().ReleaseInterface(*this);
295 // searches for the specified func
297 const SfxSlot
* SfxInterface::GetSlot( sal_uInt16 nFuncId
) const
303 // find the id using binary search
304 void* p
= bsearch( &nFuncId
, pSlots
, nCount
, sizeof(SfxSlot
),
305 SfxCompareSlots_bsearch
);
306 if ( !p
&& pGenoType
)
307 return pGenoType
->GetSlot( nFuncId
);
309 return p
? static_cast<const SfxSlot
*>(p
) : 0;
312 const SfxSlot
* SfxInterface::GetSlot( const OUString
& rCommand
) const
314 static const char UNO_COMMAND
[] = ".uno:";
316 OUString
aCommand( rCommand
);
317 if ( aCommand
.startsWith( UNO_COMMAND
) )
318 aCommand
= aCommand
.copy( sizeof( UNO_COMMAND
)-1 );
320 for ( sal_uInt16 n
=0; n
<nCount
; n
++ )
322 if ( (pSlots
+n
)->pUnoName
&&
323 aCommand
.compareToIgnoreAsciiCaseAscii( (pSlots
+n
)->GetUnoName() ) == 0 )
327 return pGenoType
? pGenoType
->GetSlot( aCommand
) : NULL
;
332 const SfxSlot
* SfxInterface::GetRealSlot( const SfxSlot
*pSlot
) const
338 if ( !ContainsSlot_Impl(pSlot
) )
341 return pGenoType
->GetRealSlot(pSlot
);
342 SAL_WARN( "sfx.control", "unknown Slot" );
346 return pSlot
->pLinkedSlot
;
351 const SfxSlot
* SfxInterface::GetRealSlot( sal_uInt16 nSlotId
) const
357 const SfxSlot
*pSlot
= GetSlot(nSlotId
);
361 return pGenoType
->GetRealSlot(nSlotId
);
362 SAL_WARN( "sfx.control", "unknown Slot" );
366 return pSlot
->pLinkedSlot
;
369 void SfxInterface::RegisterPopupMenu( const ResId
& rResId
)
372 pImpData
->aPopupRes
= rResId
;
375 void SfxInterface::RegisterObjectBar(sal_uInt16 nPos
, sal_uInt32 nResId
)
377 RegisterObjectBar(nPos
, nResId
, 0UL);
380 void SfxInterface::RegisterObjectBar(sal_uInt16 nPos
, sal_uInt32 nResId
, sal_uInt32 nFeature
)
382 SfxObjectUI_Impl
* pUI
= CreateObjectBarUI_Impl(nPos
, nResId
, nFeature
);
384 pImpData
->aObjectBars
.push_back(pUI
);
387 SfxObjectUI_Impl
* CreateObjectBarUI_Impl(sal_uInt16 nPos
, sal_uInt32 nResId
, sal_uInt32 nFeature
)
389 if ((nPos
& SFX_VISIBILITY_MASK
) == 0)
390 nPos
|= SFX_VISIBILITY_STANDARD
;
392 return new SfxObjectUI_Impl(nPos
, nResId
, true, nFeature
);
395 sal_uInt32
SfxInterface::GetObjectBarId(sal_uInt16 nNo
) const
397 bool bGenoType
= (pGenoType
!= 0 && pGenoType
->UseAsSuperClass());
400 // Are there toolbars in the super class?
401 sal_uInt16 nBaseCount
= pGenoType
->GetObjectBarCount();
402 if ( nNo
< nBaseCount
)
403 // The Super class comes first
404 return pGenoType
->GetObjectBarId(nNo
);
406 nNo
= nNo
- nBaseCount
;
409 assert( nNo
<pImpData
->aObjectBars
.size() );
411 return pImpData
->aObjectBars
[nNo
]->nResId
;
414 sal_uInt16
SfxInterface::GetObjectBarPos( sal_uInt16 nNo
) const
416 bool bGenoType
= (pGenoType
!= 0 && pGenoType
->UseAsSuperClass());
419 // Are there toolbars in the super class?
420 sal_uInt16 nBaseCount
= pGenoType
->GetObjectBarCount();
421 if ( nNo
< nBaseCount
)
422 // The Super class comes first
423 return pGenoType
->GetObjectBarPos( nNo
);
425 nNo
= nNo
- nBaseCount
;
428 assert( nNo
<pImpData
->aObjectBars
.size() );
430 return pImpData
->aObjectBars
[nNo
]->nPos
;
433 sal_uInt16
SfxInterface::GetObjectBarCount() const
435 if (pGenoType
&& pGenoType
->UseAsSuperClass())
436 return pImpData
->aObjectBars
.size() + pGenoType
->GetObjectBarCount();
438 return pImpData
->aObjectBars
.size();
441 void SfxInterface::RegisterChildWindow(sal_uInt16 nId
, bool bContext
)
443 RegisterChildWindow(nId
, bContext
, 0UL);
446 void SfxInterface::RegisterChildWindow(sal_uInt16 nId
, bool bContext
, sal_uInt32 nFeature
)
448 SfxObjectUI_Impl
* pUI
= new SfxObjectUI_Impl(0, nId
, true, nFeature
);
449 pUI
->bContext
= bContext
;
450 pImpData
->aChildWindows
.push_back(pUI
);
453 void SfxInterface::RegisterStatusBar(const ResId
& rResId
)
455 pImpData
->aStatBarRes
= rResId
;
458 sal_uInt32
SfxInterface::GetChildWindowId (sal_uInt16 nNo
) const
462 // Are there ChildWindows in der Superklasse?
463 sal_uInt16 nBaseCount
= pGenoType
->GetChildWindowCount();
464 if ( nNo
< nBaseCount
)
465 // The Super class comes first
466 return pGenoType
->GetChildWindowId( nNo
);
468 nNo
= nNo
- nBaseCount
;
471 assert( nNo
<pImpData
->aChildWindows
.size() );
473 sal_uInt32 nRet
= pImpData
->aChildWindows
[nNo
]->nResId
;
474 if ( pImpData
->aChildWindows
[nNo
]->bContext
)
475 nRet
+= sal_uInt32( nClassId
) << 16;
479 sal_uInt32
SfxInterface::GetChildWindowFeature (sal_uInt16 nNo
) const
483 // Are there ChildWindows in der Superklasse?
484 sal_uInt16 nBaseCount
= pGenoType
->GetChildWindowCount();
485 if ( nNo
< nBaseCount
)
486 // The Super class comes first
487 return pGenoType
->GetChildWindowFeature( nNo
);
489 nNo
= nNo
- nBaseCount
;
492 assert( nNo
<pImpData
->aChildWindows
.size() );
494 return pImpData
->aChildWindows
[nNo
]->nFeature
;
500 sal_uInt16
SfxInterface::GetChildWindowCount() const
503 return pImpData
->aChildWindows
.size() + pGenoType
->GetChildWindowCount();
505 return pImpData
->aChildWindows
.size();
508 const ResId
& SfxInterface::GetPopupMenuResId() const
510 return pImpData
->aPopupRes
;
513 const ResId
& SfxInterface::GetStatusBarResId() const
515 if (pImpData
->aStatBarRes
.GetId() == 0 && pGenoType
)
516 return pGenoType
->GetStatusBarResId();
518 return pImpData
->aStatBarRes
;
521 sal_uInt32
SfxInterface::GetObjectBarFeature ( sal_uInt16 nNo
) const
523 bool bGenoType
= (pGenoType
!= 0 && pGenoType
->UseAsSuperClass());
526 // Are there toolbars in the super class?
527 sal_uInt16 nBaseCount
= pGenoType
->GetObjectBarCount();
528 if ( nNo
< nBaseCount
)
529 // The Super class comes first
530 return pGenoType
->GetObjectBarFeature( nNo
);
532 nNo
= nNo
- nBaseCount
;
535 assert( nNo
<pImpData
->aObjectBars
.size() );
537 return pImpData
->aObjectBars
[nNo
]->nFeature
;
540 bool SfxInterface::IsObjectBarVisible(sal_uInt16 nNo
) const
542 bool bGenoType
= (pGenoType
!= 0 && pGenoType
->UseAsSuperClass());
545 // Are there toolbars in the super class?
546 sal_uInt16 nBaseCount
= pGenoType
->GetObjectBarCount();
547 if ( nNo
< nBaseCount
)
548 // The Super class comes first
549 return pGenoType
->IsObjectBarVisible( nNo
);
551 nNo
= nNo
- nBaseCount
;
554 assert( nNo
<pImpData
->aObjectBars
.size() );
556 return pImpData
->aObjectBars
[nNo
]->bVisible
;
559 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */