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 .
22 #include <tools/rcid.h>
23 #include <tools/stream.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>
30 #include <sfx2/sfxresid.hxx>
31 #include <sfx2/objsh.hxx>
32 #include <rtl/strbuf.hxx>
34 DBG_NAME(SfxInterface
)
36 //====================================================================
45 SfxCompareSlots_Impl( const void* pSmaller
, const void* pBigger
)
47 return ( (int) ((SfxSlot
*)pSmaller
)->GetSlotId() ) -
48 ( (int) ((SfxSlot
*)pBigger
)->GetSlotId() );
51 //=========================================================================
53 struct SfxObjectUI_Impl
62 SfxObjectUI_Impl(sal_uInt16 n
, const ResId
& rResId
, sal_Bool bVis
, sal_uInt32 nFeat
) :
64 aResId(rResId
.GetId(), *rResId
.GetResMgr()),
70 aResId
.SetRT(rResId
.GetRT());
79 typedef std::vector
<SfxObjectUI_Impl
*> SfxObjectUIArr_Impl
;
81 struct SfxInterface_Impl
83 SfxObjectUIArr_Impl aObjectBars
; // registered ObjectBars
84 SfxObjectUIArr_Impl aChildWindows
; // registered ChildWindows
85 ResId aPopupRes
; // registered PopupMenu
86 ResId aStatBarRes
; // registered StatusBar
91 aPopupRes(0,*SfxApplication::GetOrCreate()->GetSfxResManager()),
92 aStatBarRes(0,*SfxApplication::GetOrCreate()->GetSfxResManager())
94 , bRegistered(sal_False
)
100 for (SfxObjectUIArr_Impl::const_iterator it
= aObjectBars
.begin(); it
!= aObjectBars
.end(); ++it
)
103 for (SfxObjectUIArr_Impl::const_iterator it
= aChildWindows
.begin(); it
!= aChildWindows
.end(); ++it
)
108 static SfxObjectUI_Impl
* CreateObjectBarUI_Impl( sal_uInt16 nPos
, const ResId
& rResId
, sal_uInt32 nFeature
, const OUString
*pStr
);
110 //====================================================================
112 //====================================================================
113 // constuctor, registeres a new unit
115 SfxInterface::SfxInterface( const char *pClassName
,
116 const ResId
& rNameResId
,
118 const SfxInterface
* pParent
,
119 SfxSlot
&rSlotMap
, sal_uInt16 nSlotCount
):
123 aNameResId(rNameResId
.GetId(),*rNameResId
.GetResMgr()),
126 pImpData
= new SfxInterface_Impl
;
127 SetSlotMap( rSlotMap
, nSlotCount
);
130 void SfxInterface::Register( SfxModule
* pMod
)
132 pImpData
->bRegistered
= sal_True
;
133 pImpData
->pModule
= pMod
;
135 pMod
->GetSlotPool()->RegisterInterface(*this);
137 SFX_APP()->GetAppSlotPool_Impl().RegisterInterface(*this);
140 void SfxInterface::SetSlotMap( SfxSlot
& rSlotMap
, sal_uInt16 nSlotCount
)
144 SfxSlot
* pIter
= pSlots
;
145 if ( 1 == nCount
&& !pIter
->pNextSlot
)
146 pIter
->pNextSlot
= pIter
;
148 if ( !pIter
->pNextSlot
)
150 // sort the SfxSlots by id
151 qsort( pSlots
, nCount
, sizeof(SfxSlot
), SfxCompareSlots_Impl
);
153 // link masters and slaves
154 sal_uInt16 nIter
= 1;
155 for ( pIter
= pSlots
; nIter
<= nCount
; ++pIter
, ++nIter
)
158 DBG_ASSERT( nIter
== nCount
||
159 pIter
->GetSlotId() != (pIter
+1)->GetSlotId(),
162 // every master refers to his first slave (ENUM),
163 // all slaves refer to their master.
164 // Slaves refer in a circle to the other slaves with the same master
165 if ( pIter
->GetKind() == SFX_KIND_ENUM
)
167 pIter
->pLinkedSlot
= GetSlot( pIter
->nMasterSlotId
);
168 DBG_ASSERT( pIter
->pLinkedSlot
, "slave without master" );
169 if ( !pIter
->pLinkedSlot
->pLinkedSlot
)
170 ( (SfxSlot
*) pIter
->pLinkedSlot
)->pLinkedSlot
= pIter
;
172 if ( 0 == pIter
->GetNextSlot() )
174 SfxSlot
*pLastSlot
= pIter
;
175 for ( sal_uInt16 n
= nIter
; n
< Count(); ++n
)
177 SfxSlot
*pCurSlot
= (pSlots
+n
);
178 if ( pCurSlot
->nMasterSlotId
== pIter
->nMasterSlotId
)
180 pLastSlot
->pNextSlot
= pCurSlot
;
181 pLastSlot
= pCurSlot
;
184 pLastSlot
->pNextSlot
= pIter
;
187 else if ( 0 == pIter
->GetNextSlot() )
189 // Slots refering in circle to the next with the same
191 SfxSlot
*pLastSlot
= pIter
;
192 for ( sal_uInt16 n
= nIter
; n
< Count(); ++n
)
194 SfxSlot
*pCurSlot
= (pSlots
+n
);
195 if ( pCurSlot
->GetStateFnc() == pIter
->GetStateFnc() )
197 pLastSlot
->pNextSlot
= pCurSlot
;
198 pLastSlot
= pCurSlot
;
201 pLastSlot
->pNextSlot
= pIter
;
208 sal_uInt16 nIter
= 1;
209 for ( SfxSlot
*pNext
= pIter
+1; nIter
< nCount
; ++pNext
, ++nIter
)
212 if ( pNext
->GetSlotId() <= pIter
->GetSlotId() )
213 OSL_FAIL("Wrong order!");
215 if ( pIter
->GetKind() == SFX_KIND_ENUM
)
217 const SfxSlot
*pMasterSlot
= GetSlot(pIter
->nMasterSlotId
);
218 const SfxSlot
*pFirstSlave
= pMasterSlot
->pLinkedSlot
;
219 const SfxSlot
*pSlave
= pFirstSlave
;
222 if ( pSlave
->pLinkedSlot
!= pMasterSlot
)
224 OStringBuffer
aStr("Wrong Master/Slave- link: ");
225 aStr
.append(static_cast<sal_Int32
>(
226 pMasterSlot
->GetSlotId()));
228 aStr
.append(static_cast<sal_Int32
>(
229 pSlave
->GetSlotId()));
230 OSL_FAIL(aStr
.getStr());
233 if ( pSlave
->nMasterSlotId
!= pMasterSlot
->GetSlotId() )
235 OStringBuffer
aStr("Wrong Master/Slave-Ids: ");
236 aStr
.append(static_cast<sal_Int32
>(
237 pMasterSlot
->GetSlotId()));
239 aStr
.append(static_cast<sal_Int32
>(
240 pSlave
->GetSlotId()));
241 OSL_FAIL(aStr
.getStr());
244 pSlave
= pSlave
->pNextSlot
;
246 while ( pSlave
!= pFirstSlave
);
250 if ( pIter
->pLinkedSlot
)
252 if ( pIter
->pLinkedSlot
->GetKind() != SFX_KIND_ENUM
)
254 OStringBuffer
aStr("Slave is no enum: ");
255 aStr
.append(static_cast<sal_Int32
>(pIter
->GetSlotId()));
257 aStr
.append(static_cast<sal_Int32
>(
258 pIter
->pLinkedSlot
->GetSlotId()));
259 OSL_FAIL(aStr
.getStr());
263 const SfxSlot
*pCurSlot
= pIter
;
266 pCurSlot
= pCurSlot
->pNextSlot
;
267 if ( pCurSlot
->GetStateFnc() != pIter
->GetStateFnc() )
269 OStringBuffer
aStr("Linked Slots with different State Methods : ");
270 aStr
.append(static_cast<sal_Int32
>(
271 pCurSlot
->GetSlotId()));
273 aStr
.append(static_cast<sal_Int32
>(pIter
->GetSlotId()));
274 OSL_FAIL(aStr
.getStr());
277 while ( pCurSlot
!= pIter
);
286 //--------------------------------------------------------------------
288 SfxInterface::~SfxInterface()
290 SfxModule
*pMod
= pImpData
->pModule
;
291 sal_Bool bRegistered
= pImpData
->bRegistered
;
293 DBG_ASSERT( bRegistered
, "Interface not registered!" );
297 pMod
->GetSlotPool()->ReleaseInterface(*this);
299 SFX_APP()->GetAppSlotPool_Impl().ReleaseInterface(*this);
303 //--------------------------------------------------------------------
305 // searches for the specified func
307 const SfxSlot
* SfxInterface::GetSlot( sal_uInt16 nFuncId
) const
309 DBG_CHKTHIS(SfxInterface
, 0);
310 DBG_ASSERT( this && pSlots
&& nCount
, "" );
312 // find the id using binary search
313 void* p
= bsearch( &nFuncId
, pSlots
, nCount
, sizeof(SfxSlot
),
314 SfxCompareSlots_Impl
);
315 if ( !p
&& pGenoType
)
316 return pGenoType
->GetSlot( nFuncId
);
318 return p
? (const SfxSlot
*)p
: 0;
321 const SfxSlot
* SfxInterface::GetSlot( const OUString
& rCommand
) const
323 static const char UNO_COMMAND
[] = ".uno:";
325 OUString
aCommand( rCommand
);
326 if ( aCommand
.startsWith( UNO_COMMAND
) )
327 aCommand
= aCommand
.copy( sizeof( UNO_COMMAND
)-1 );
329 for ( sal_uInt16 n
=0; n
<nCount
; n
++ )
331 if ( (pSlots
+n
)->pUnoName
&&
332 aCommand
.compareToIgnoreAsciiCaseAscii( (pSlots
+n
)->GetUnoName() ) == 0 )
336 return pGenoType
? pGenoType
->GetSlot( aCommand
) : NULL
;
339 //--------------------------------------------------------------------
341 const SfxSlot
* SfxInterface::GetRealSlot( const SfxSlot
*pSlot
) const
343 DBG_CHKTHIS(SfxInterface
, 0);
344 DBG_ASSERT( this && pSlots
&& nCount
, "" );
346 if ( !ContainsSlot_Impl(pSlot
) )
349 return pGenoType
->GetRealSlot(pSlot
);
350 OSL_FAIL("unknown Slot");
354 return pSlot
->pLinkedSlot
;
357 //--------------------------------------------------------------------
359 const SfxSlot
* SfxInterface::GetRealSlot( sal_uInt16 nSlotId
) const
361 DBG_CHKTHIS(SfxInterface
, 0);
362 DBG_ASSERT( this && pSlots
&& nCount
, "" );
364 const SfxSlot
*pSlot
= GetSlot(nSlotId
);
368 return pGenoType
->GetRealSlot(nSlotId
);
369 OSL_FAIL("unkonown Slot");
373 return pSlot
->pLinkedSlot
;
376 //--------------------------------------------------------------------
378 void SfxInterface::RegisterPopupMenu( const ResId
& rResId
)
380 DBG_CHKTHIS(SfxInterface
, 0);
381 pImpData
->aPopupRes
= rResId
;
384 //--------------------------------------------------------------------
386 void SfxInterface::RegisterObjectBar( sal_uInt16 nPos
, const ResId
& rResId
,
387 const OUString
*pStr
)
389 RegisterObjectBar( nPos
, rResId
, 0UL, pStr
);
393 void SfxInterface::RegisterObjectBar( sal_uInt16 nPos
, const ResId
& rResId
, sal_uInt32 nFeature
, const OUString
*pStr
)
395 SfxObjectUI_Impl
* pUI
= CreateObjectBarUI_Impl( nPos
, rResId
, nFeature
, pStr
);
397 pImpData
->aObjectBars
.push_back(pUI
);
400 SfxObjectUI_Impl
* CreateObjectBarUI_Impl( sal_uInt16 nPos
, const ResId
& rResId
, sal_uInt32 nFeature
, const OUString
*pStr
)
402 if ((nPos
& SFX_VISIBILITY_MASK
) == 0)
403 nPos
|= SFX_VISIBILITY_STANDARD
;
405 SfxObjectUI_Impl
* pUI
= new SfxObjectUI_Impl(nPos
, rResId
, sal_True
, nFeature
);
409 ResId
aResId(rResId
);
410 aResId
.SetRT(RSC_STRING
);
411 aResId
.SetResMgr(rResId
.GetResMgr());
412 if( ! aResId
.GetResMgr() )
413 aResId
.SetResMgr( SfxApplication::GetOrCreate()->GetOffResManager_Impl() );
414 if ( !aResId
.GetResMgr() || !aResId
.GetResMgr()->IsAvailable(aResId
) )
415 pUI
->pName
= new OUString ("NoName");
417 pUI
->pName
= new OUString(aResId
.toString());
420 pUI
->pName
= new OUString(*pStr
);
425 const ResId
& SfxInterface::GetObjectBarResId( sal_uInt16 nNo
) const
427 sal_Bool bGenoType
= (pGenoType
!= 0 && !pGenoType
->HasName());
430 // Are there toolbars in the super class?
431 sal_uInt16 nBaseCount
= pGenoType
->GetObjectBarCount();
432 if ( nNo
< nBaseCount
)
433 // The Super class comes first
434 return pGenoType
->GetObjectBarResId( nNo
);
436 nNo
= nNo
- nBaseCount
;
440 sal_uInt16 nObjBarCount
= pImpData
->aObjectBars
.size();
441 DBG_ASSERT( nNo
<nObjBarCount
,"Objectbar is unknown!" );
443 return pImpData
->aObjectBars
[nNo
]->aResId
;
446 //--------------------------------------------------------------------
449 sal_uInt16
SfxInterface::GetObjectBarPos( sal_uInt16 nNo
) const
451 sal_Bool bGenoType
= (pGenoType
!= 0 && !pGenoType
->HasName());
454 // Are there toolbars in the super class?
455 sal_uInt16 nBaseCount
= pGenoType
->GetObjectBarCount();
456 if ( nNo
< nBaseCount
)
457 // The Super class comes first
458 return pGenoType
->GetObjectBarPos( nNo
);
460 nNo
= nNo
- nBaseCount
;
464 sal_uInt16 nObjBarCount
= pImpData
->aObjectBars
.size();
465 DBG_ASSERT( nNo
<nObjBarCount
,"Objectbar is unknown!" );
467 return pImpData
->aObjectBars
[nNo
]->nPos
;
470 //--------------------------------------------------------------------
473 sal_uInt16
SfxInterface::GetObjectBarCount() const
475 if (pGenoType
&& ! pGenoType
->HasName())
476 return pImpData
->aObjectBars
.size() + pGenoType
->GetObjectBarCount();
478 return pImpData
->aObjectBars
.size();
481 //--------------------------------------------------------------------
482 void SfxInterface::RegisterChildWindow(sal_uInt16 nId
, sal_Bool bContext
, const OUString
* pChildWinName
)
484 RegisterChildWindow( nId
, bContext
, 0UL, pChildWinName
);
487 void SfxInterface::RegisterChildWindow(sal_uInt16 nId
, sal_Bool bContext
, sal_uInt32 nFeature
, const OUString
*)
489 SfxObjectUI_Impl
* pUI
= new SfxObjectUI_Impl(0, ResId(nId
, *SfxApplication::GetOrCreate()->GetOffResManager_Impl()), sal_True
, nFeature
);
490 pUI
->bContext
= bContext
;
491 pImpData
->aChildWindows
.push_back(pUI
);
494 void SfxInterface::RegisterStatusBar(const ResId
& rResId
)
496 pImpData
->aStatBarRes
= rResId
;
500 sal_uInt32
SfxInterface::GetChildWindowId (sal_uInt16 nNo
) const
504 // Are there ChildWindows in der Superklasse?
505 sal_uInt16 nBaseCount
= pGenoType
->GetChildWindowCount();
506 if ( nNo
< nBaseCount
)
507 // The Super class comes first
508 return pGenoType
->GetChildWindowId( nNo
);
510 nNo
= nNo
- nBaseCount
;
514 sal_uInt16 nCWCount
= pImpData
->aChildWindows
.size();
515 DBG_ASSERT( nNo
<nCWCount
,"ChildWindow is unknown!" );
517 sal_uInt32 nRet
= pImpData
->aChildWindows
[nNo
]->aResId
.GetId();
518 if ( pImpData
->aChildWindows
[nNo
]->bContext
)
519 nRet
+= sal_uInt32( nClassId
) << 16;
523 sal_uInt32
SfxInterface::GetChildWindowFeature (sal_uInt16 nNo
) const
527 // Are there ChildWindows in der Superklasse?
528 sal_uInt16 nBaseCount
= pGenoType
->GetChildWindowCount();
529 if ( nNo
< nBaseCount
)
530 // The Super class comes first
531 return pGenoType
->GetChildWindowFeature( nNo
);
533 nNo
= nNo
- nBaseCount
;
537 sal_uInt16 nCWCount
= pImpData
->aChildWindows
.size();
538 DBG_ASSERT( nNo
<nCWCount
,"ChildWindow is unknown!" );
540 return pImpData
->aChildWindows
[nNo
]->nFeature
;
543 //--------------------------------------------------------------------
546 sal_uInt16
SfxInterface::GetChildWindowCount() const
549 return pImpData
->aChildWindows
.size() + pGenoType
->GetChildWindowCount();
551 return pImpData
->aChildWindows
.size();
555 const ResId
& SfxInterface::GetPopupMenuResId() const
557 return pImpData
->aPopupRes
;
561 const ResId
& SfxInterface::GetStatusBarResId() const
563 if (pImpData
->aStatBarRes
.GetId() == 0 && pGenoType
)
564 return pGenoType
->GetStatusBarResId();
566 return pImpData
->aStatBarRes
;
571 const OUString
* SfxInterface::GetObjectBarName ( sal_uInt16 nNo
) const
573 sal_Bool bGenoType
= (pGenoType
!= 0 && !pGenoType
->HasName());
576 // Are there toolbars in the super class?
577 sal_uInt16 nBaseCount
= pGenoType
->GetObjectBarCount();
578 if ( nNo
< nBaseCount
)
579 // The Super class comes first
580 return pGenoType
->GetObjectBarName( nNo
);
582 nNo
= nNo
- nBaseCount
;
586 sal_uInt16 nObjBarCount
= pImpData
->aObjectBars
.size();
587 DBG_ASSERT( nNo
<nObjBarCount
,"Objectbar is unknown!" );
589 return pImpData
->aObjectBars
[nNo
]->pName
;
592 sal_uInt32
SfxInterface::GetObjectBarFeature ( sal_uInt16 nNo
) const
594 sal_Bool bGenoType
= (pGenoType
!= 0 && !pGenoType
->HasName());
597 // Are there toolbars in the super class?
598 sal_uInt16 nBaseCount
= pGenoType
->GetObjectBarCount();
599 if ( nNo
< nBaseCount
)
600 // The Super class comes first
601 return pGenoType
->GetObjectBarFeature( nNo
);
603 nNo
= nNo
- nBaseCount
;
607 sal_uInt16 nObjBarCount
= pImpData
->aObjectBars
.size();
608 DBG_ASSERT( nNo
<nObjBarCount
,"Objectbar is unknown!" );
610 return pImpData
->aObjectBars
[nNo
]->nFeature
;
613 sal_Bool
SfxInterface::IsObjectBarVisible(sal_uInt16 nNo
) const
615 sal_Bool bGenoType
= (pGenoType
!= 0 && !pGenoType
->HasName());
618 // Are there toolbars in the super class?
619 sal_uInt16 nBaseCount
= pGenoType
->GetObjectBarCount();
620 if ( nNo
< nBaseCount
)
621 // The Super class comes first
622 return pGenoType
->IsObjectBarVisible( nNo
);
624 nNo
= nNo
- nBaseCount
;
628 sal_uInt16 nObjBarCount
= pImpData
->aObjectBars
.size();
629 DBG_ASSERT( nNo
<nObjBarCount
,"Objectbar is unknown!" );
631 return pImpData
->aObjectBars
[nNo
]->bVisible
;
634 const SfxInterface
* SfxInterface::GetRealInterfaceForSlot( const SfxSlot
*pRealSlot
) const
636 DBG_ASSERT( pImpData
->bRegistered
, "Interface not registered!" );
637 const SfxInterface
* pInterface
= this;
639 // The slot could also originate from the interface of a shell base class.
642 const SfxSlot
*pLastSlot
= (*pInterface
)[pInterface
->Count()-1];
643 const SfxSlot
*pFirstSlot
= (*pInterface
)[0];
645 // Is pInterface the Owner of pRealSlot ?
646 if ( pFirstSlot
<= pRealSlot
&& pRealSlot
<= pLastSlot
)
649 // Otherwise try the Interface of Super class
650 pInterface
= pInterface
->pGenoType
;
652 while ( pInterface
);
657 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */