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 String
*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(RTL_CONSTASCII_STRINGPARAM(
225 "Wrong Master/Slave- link: "));
226 aStr
.append(static_cast<sal_Int32
>(
227 pMasterSlot
->GetSlotId()));
228 aStr
.append(RTL_CONSTASCII_STRINGPARAM(" , "));
229 aStr
.append(static_cast<sal_Int32
>(
230 pSlave
->GetSlotId()));
231 OSL_FAIL(aStr
.getStr());
234 if ( pSlave
->nMasterSlotId
!= pMasterSlot
->GetSlotId() )
236 OStringBuffer
aStr(RTL_CONSTASCII_STRINGPARAM(
237 "Wrong Master/Slave-Ids: "));
238 aStr
.append(static_cast<sal_Int32
>(
239 pMasterSlot
->GetSlotId()));
240 aStr
.append(RTL_CONSTASCII_STRINGPARAM(" , "));
241 aStr
.append(static_cast<sal_Int32
>(
242 pSlave
->GetSlotId()));
243 OSL_FAIL(aStr
.getStr());
246 pSlave
= pSlave
->pNextSlot
;
248 while ( pSlave
!= pFirstSlave
);
252 if ( pIter
->pLinkedSlot
)
254 if ( pIter
->pLinkedSlot
->GetKind() != SFX_KIND_ENUM
)
256 OStringBuffer
aStr(RTL_CONSTASCII_STRINGPARAM(
257 "Slave is no enum: "));
258 aStr
.append(static_cast<sal_Int32
>(pIter
->GetSlotId()));
259 aStr
.append(RTL_CONSTASCII_STRINGPARAM(" , "));
260 aStr
.append(static_cast<sal_Int32
>(
261 pIter
->pLinkedSlot
->GetSlotId()));
262 OSL_FAIL(aStr
.getStr());
266 const SfxSlot
*pCurSlot
= pIter
;
269 pCurSlot
= pCurSlot
->pNextSlot
;
270 if ( pCurSlot
->GetStateFnc() != pIter
->GetStateFnc() )
272 OStringBuffer
aStr(RTL_CONSTASCII_STRINGPARAM(
273 "Linked Slots with different State Methods : "));
274 aStr
.append(static_cast<sal_Int32
>(
275 pCurSlot
->GetSlotId()));
276 aStr
.append(RTL_CONSTASCII_STRINGPARAM(" , "));
277 aStr
.append(static_cast<sal_Int32
>(pIter
->GetSlotId()));
278 OSL_FAIL(aStr
.getStr());
281 while ( pCurSlot
!= pIter
);
290 //--------------------------------------------------------------------
292 SfxInterface::~SfxInterface()
294 SfxModule
*pMod
= pImpData
->pModule
;
295 sal_Bool bRegistered
= pImpData
->bRegistered
;
297 DBG_ASSERT( bRegistered
, "Interface not registered!" );
301 pMod
->GetSlotPool()->ReleaseInterface(*this);
303 SFX_APP()->GetAppSlotPool_Impl().ReleaseInterface(*this);
307 //--------------------------------------------------------------------
309 // searches for the specified func
311 const SfxSlot
* SfxInterface::GetSlot( sal_uInt16 nFuncId
) const
313 DBG_CHKTHIS(SfxInterface
, 0);
314 DBG_ASSERT( this && pSlots
&& nCount
, "" );
316 // find the id using binary search
317 void* p
= bsearch( &nFuncId
, pSlots
, nCount
, sizeof(SfxSlot
),
318 SfxCompareSlots_Impl
);
319 if ( !p
&& pGenoType
)
320 return pGenoType
->GetSlot( nFuncId
);
322 return p
? (const SfxSlot
*)p
: 0;
325 const SfxSlot
* SfxInterface::GetSlot( const String
& rCommand
) const
327 static const char UNO_COMMAND
[] = ".uno:";
329 String
aCommand( rCommand
);
330 if ( aCommand
.SearchAscii( UNO_COMMAND
) == 0 )
331 aCommand
.Erase( 0, sizeof( UNO_COMMAND
)-1 );
333 for ( sal_uInt16 n
=0; n
<nCount
; n
++ )
335 if ( (pSlots
+n
)->pUnoName
&&
336 aCommand
.CompareIgnoreCaseToAscii( (pSlots
+n
)->GetUnoName() ) == COMPARE_EQUAL
)
340 return pGenoType
? pGenoType
->GetSlot( aCommand
) : NULL
;
343 //--------------------------------------------------------------------
345 const SfxSlot
* SfxInterface::GetRealSlot( const SfxSlot
*pSlot
) const
347 DBG_CHKTHIS(SfxInterface
, 0);
348 DBG_ASSERT( this && pSlots
&& nCount
, "" );
350 if ( !ContainsSlot_Impl(pSlot
) )
353 return pGenoType
->GetRealSlot(pSlot
);
354 OSL_FAIL("unknown Slot");
358 return pSlot
->pLinkedSlot
;
361 //--------------------------------------------------------------------
363 const SfxSlot
* SfxInterface::GetRealSlot( sal_uInt16 nSlotId
) const
365 DBG_CHKTHIS(SfxInterface
, 0);
366 DBG_ASSERT( this && pSlots
&& nCount
, "" );
368 const SfxSlot
*pSlot
= GetSlot(nSlotId
);
372 return pGenoType
->GetRealSlot(nSlotId
);
373 OSL_FAIL("unkonown Slot");
377 return pSlot
->pLinkedSlot
;
380 //--------------------------------------------------------------------
382 void SfxInterface::RegisterPopupMenu( const ResId
& rResId
)
384 DBG_CHKTHIS(SfxInterface
, 0);
385 pImpData
->aPopupRes
= rResId
;
388 //--------------------------------------------------------------------
390 void SfxInterface::RegisterObjectBar( sal_uInt16 nPos
, const ResId
& rResId
,
393 RegisterObjectBar( nPos
, rResId
, 0UL, pStr
);
397 void SfxInterface::RegisterObjectBar( sal_uInt16 nPos
, const ResId
& rResId
, sal_uInt32 nFeature
, const String
*pStr
)
399 SfxObjectUI_Impl
* pUI
= CreateObjectBarUI_Impl( nPos
, rResId
, nFeature
, pStr
);
401 pImpData
->aObjectBars
.push_back(pUI
);
404 SfxObjectUI_Impl
* CreateObjectBarUI_Impl( sal_uInt16 nPos
, const ResId
& rResId
, sal_uInt32 nFeature
, const String
*pStr
)
406 if ((nPos
& SFX_VISIBILITY_MASK
) == 0)
407 nPos
|= SFX_VISIBILITY_STANDARD
;
409 SfxObjectUI_Impl
* pUI
= new SfxObjectUI_Impl(nPos
, rResId
, sal_True
, nFeature
);
413 ResId
aResId(rResId
);
414 aResId
.SetRT(RSC_STRING
);
415 aResId
.SetResMgr(rResId
.GetResMgr());
416 if( ! aResId
.GetResMgr() )
417 aResId
.SetResMgr( SfxApplication::GetOrCreate()->GetOffResManager_Impl() );
418 if ( !aResId
.GetResMgr() || !aResId
.GetResMgr()->IsAvailable(aResId
) )
419 pUI
->pName
= new String ("NoName");
421 pUI
->pName
= new String(aResId
.toString());
424 pUI
->pName
= new String(*pStr
);
429 const ResId
& SfxInterface::GetObjectBarResId( sal_uInt16 nNo
) const
431 sal_Bool bGenoType
= (pGenoType
!= 0 && !pGenoType
->HasName());
434 // Are there toolbars in the super class?
435 sal_uInt16 nBaseCount
= pGenoType
->GetObjectBarCount();
436 if ( nNo
< nBaseCount
)
437 // The Super class comes first
438 return pGenoType
->GetObjectBarResId( nNo
);
440 nNo
= nNo
- nBaseCount
;
444 sal_uInt16 nObjBarCount
= pImpData
->aObjectBars
.size();
445 DBG_ASSERT( nNo
<nObjBarCount
,"Objectbar is unknown!" );
447 return pImpData
->aObjectBars
[nNo
]->aResId
;
450 //--------------------------------------------------------------------
453 sal_uInt16
SfxInterface::GetObjectBarPos( sal_uInt16 nNo
) const
455 sal_Bool bGenoType
= (pGenoType
!= 0 && !pGenoType
->HasName());
458 // Are there toolbars in the super class?
459 sal_uInt16 nBaseCount
= pGenoType
->GetObjectBarCount();
460 if ( nNo
< nBaseCount
)
461 // The Super class comes first
462 return pGenoType
->GetObjectBarPos( nNo
);
464 nNo
= nNo
- nBaseCount
;
468 sal_uInt16 nObjBarCount
= pImpData
->aObjectBars
.size();
469 DBG_ASSERT( nNo
<nObjBarCount
,"Objectbar is unknown!" );
471 return pImpData
->aObjectBars
[nNo
]->nPos
;
474 //--------------------------------------------------------------------
477 sal_uInt16
SfxInterface::GetObjectBarCount() const
479 if (pGenoType
&& ! pGenoType
->HasName())
480 return pImpData
->aObjectBars
.size() + pGenoType
->GetObjectBarCount();
482 return pImpData
->aObjectBars
.size();
485 //--------------------------------------------------------------------
486 void SfxInterface::RegisterChildWindow(sal_uInt16 nId
, sal_Bool bContext
, const String
* pChildWinName
)
488 RegisterChildWindow( nId
, bContext
, 0UL, pChildWinName
);
491 void SfxInterface::RegisterChildWindow(sal_uInt16 nId
, sal_Bool bContext
, sal_uInt32 nFeature
, const String
*)
493 SfxObjectUI_Impl
* pUI
= new SfxObjectUI_Impl(0, ResId(nId
, *SfxApplication::GetOrCreate()->GetOffResManager_Impl()), sal_True
, nFeature
);
494 pUI
->bContext
= bContext
;
495 pImpData
->aChildWindows
.push_back(pUI
);
498 void SfxInterface::RegisterStatusBar(const ResId
& rResId
)
500 pImpData
->aStatBarRes
= rResId
;
504 sal_uInt32
SfxInterface::GetChildWindowId (sal_uInt16 nNo
) const
508 // Are there ChildWindows in der Superklasse?
509 sal_uInt16 nBaseCount
= pGenoType
->GetChildWindowCount();
510 if ( nNo
< nBaseCount
)
511 // The Super class comes first
512 return pGenoType
->GetChildWindowId( nNo
);
514 nNo
= nNo
- nBaseCount
;
518 sal_uInt16 nCWCount
= pImpData
->aChildWindows
.size();
519 DBG_ASSERT( nNo
<nCWCount
,"ChildWindow is unknown!" );
521 sal_uInt32 nRet
= pImpData
->aChildWindows
[nNo
]->aResId
.GetId();
522 if ( pImpData
->aChildWindows
[nNo
]->bContext
)
523 nRet
+= sal_uInt32( nClassId
) << 16;
527 sal_uInt32
SfxInterface::GetChildWindowFeature (sal_uInt16 nNo
) const
531 // Are there ChildWindows in der Superklasse?
532 sal_uInt16 nBaseCount
= pGenoType
->GetChildWindowCount();
533 if ( nNo
< nBaseCount
)
534 // The Super class comes first
535 return pGenoType
->GetChildWindowFeature( nNo
);
537 nNo
= nNo
- nBaseCount
;
541 sal_uInt16 nCWCount
= pImpData
->aChildWindows
.size();
542 DBG_ASSERT( nNo
<nCWCount
,"ChildWindow is unknown!" );
544 return pImpData
->aChildWindows
[nNo
]->nFeature
;
547 //--------------------------------------------------------------------
550 sal_uInt16
SfxInterface::GetChildWindowCount() const
553 return pImpData
->aChildWindows
.size() + pGenoType
->GetChildWindowCount();
555 return pImpData
->aChildWindows
.size();
559 const ResId
& SfxInterface::GetPopupMenuResId() const
561 return pImpData
->aPopupRes
;
565 const ResId
& SfxInterface::GetStatusBarResId() const
567 if (pImpData
->aStatBarRes
.GetId() == 0 && pGenoType
)
568 return pGenoType
->GetStatusBarResId();
570 return pImpData
->aStatBarRes
;
575 const String
* SfxInterface::GetObjectBarName ( sal_uInt16 nNo
) const
577 sal_Bool bGenoType
= (pGenoType
!= 0 && !pGenoType
->HasName());
580 // Are there toolbars in the super class?
581 sal_uInt16 nBaseCount
= pGenoType
->GetObjectBarCount();
582 if ( nNo
< nBaseCount
)
583 // The Super class comes first
584 return pGenoType
->GetObjectBarName( nNo
);
586 nNo
= nNo
- nBaseCount
;
590 sal_uInt16 nObjBarCount
= pImpData
->aObjectBars
.size();
591 DBG_ASSERT( nNo
<nObjBarCount
,"Objectbar is unknown!" );
593 return pImpData
->aObjectBars
[nNo
]->pName
;
596 sal_uInt32
SfxInterface::GetObjectBarFeature ( sal_uInt16 nNo
) const
598 sal_Bool bGenoType
= (pGenoType
!= 0 && !pGenoType
->HasName());
601 // Are there toolbars in the super class?
602 sal_uInt16 nBaseCount
= pGenoType
->GetObjectBarCount();
603 if ( nNo
< nBaseCount
)
604 // The Super class comes first
605 return pGenoType
->GetObjectBarFeature( nNo
);
607 nNo
= nNo
- nBaseCount
;
611 sal_uInt16 nObjBarCount
= pImpData
->aObjectBars
.size();
612 DBG_ASSERT( nNo
<nObjBarCount
,"Objectbar is unknown!" );
614 return pImpData
->aObjectBars
[nNo
]->nFeature
;
617 sal_Bool
SfxInterface::IsObjectBarVisible(sal_uInt16 nNo
) const
619 sal_Bool bGenoType
= (pGenoType
!= 0 && !pGenoType
->HasName());
622 // Are there toolbars in the super class?
623 sal_uInt16 nBaseCount
= pGenoType
->GetObjectBarCount();
624 if ( nNo
< nBaseCount
)
625 // The Super class comes first
626 return pGenoType
->IsObjectBarVisible( nNo
);
628 nNo
= nNo
- nBaseCount
;
632 sal_uInt16 nObjBarCount
= pImpData
->aObjectBars
.size();
633 DBG_ASSERT( nNo
<nObjBarCount
,"Objectbar is unknown!" );
635 return pImpData
->aObjectBars
[nNo
]->bVisible
;
638 const SfxInterface
* SfxInterface::GetRealInterfaceForSlot( const SfxSlot
*pRealSlot
) const
640 DBG_ASSERT( pImpData
->bRegistered
, "Interface not registered!" );
641 const SfxInterface
* pInterface
= this;
643 // The slot could also originate from the interface of a shell base class.
646 const SfxSlot
*pLastSlot
= (*pInterface
)[pInterface
->Count()-1];
647 const SfxSlot
*pFirstSlot
= (*pInterface
)[0];
649 // Is pInterface the Owner of pRealSlot ?
650 if ( pFirstSlot
<= pRealSlot
&& pRealSlot
<= pLastSlot
)
653 // Otherwise try the Interface of Super class
654 pInterface
= pInterface
->pGenoType
;
656 while ( pInterface
);
661 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */