1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: objface.cxx,v $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_sfx2.hxx"
35 #include <tools/rcid.h>
38 #include <tools/stream.hxx>
40 #include <sfx2/module.hxx>
41 #include <sfx2/objface.hxx>
42 #include <sfx2/msg.hxx>
43 #include <sfx2/app.hxx>
44 #include <sfx2/msgpool.hxx>
45 #include "sfxresid.hxx"
46 #include <sfx2/minarray.hxx>
47 #include <sfx2/objsh.hxx>
49 DBG_NAME(SfxInterface
)
51 //====================================================================
54 #if defined( PM2 ) && (!defined( CSET ) && !defined ( MTW ) && !defined( WTC ))
64 SfxCompareSlots_Impl( const void* pSmaller
, const void* pBigger
)
67 return ( (int) ((SfxSlot
*)pSmaller
)->GetSlotId() ) -
68 ( (int) ((SfxSlot
*)pBigger
)->GetSlotId() );
71 //=========================================================================
73 struct SfxObjectUI_Impl
82 SfxObjectUI_Impl(USHORT n
, const ResId
& rResId
, BOOL bVis
, sal_uInt32 nFeat
) :
84 aResId(rResId
.GetId(), *rResId
.GetResMgr()),
90 aResId
.SetRT(rResId
.GetRT());
99 DECL_PTRARRAY(SfxObjectUIArr_Impl
, SfxObjectUI_Impl
*, 2, 2)
101 struct SfxInterface_Impl
103 SfxObjectUIArr_Impl
* pObjectBars
; // registered ObjectBars
104 SfxObjectUIArr_Impl
* pChildWindows
; // registered ChildWindows
105 ResId aPopupRes
; // registered PopupMenu
106 ResId aStatBarRes
; // registered StatusBar
110 SfxInterface_Impl() :
111 aPopupRes(0,*SfxApplication::GetOrCreate()->GetSfxResManager()),
112 aStatBarRes(0,*SfxApplication::GetOrCreate()->GetSfxResManager())
115 pObjectBars
= new SfxObjectUIArr_Impl
;
116 pChildWindows
= new SfxObjectUIArr_Impl
;
122 for (n
=0; n
<pObjectBars
->Count(); n
++)
123 delete (*pObjectBars
)[n
];
126 for (n
=0; n
<pChildWindows
->Count(); n
++)
127 delete (*pChildWindows
)[n
];
128 delete pChildWindows
;
132 static SfxObjectUI_Impl
* CreateObjectBarUI_Impl( USHORT nPos
, const ResId
& rResId
, sal_uInt32 nFeature
, const String
*pStr
);
134 //====================================================================
136 //====================================================================
137 // ctor, registeres a new unit
139 SfxInterface::SfxInterface( const char *pClassName
,
140 const ResId
& rNameResId
,
142 const SfxInterface
* pParent
,
143 SfxSlot
&rSlotMap
, USHORT nSlotCount
):
147 aNameResId(rNameResId
.GetId(),*rNameResId
.GetResMgr()),
150 pImpData
= new SfxInterface_Impl
;
151 SetSlotMap( rSlotMap
, nSlotCount
);
154 void SfxInterface::Register( SfxModule
* pMod
)
156 pImpData
->bRegistered
= TRUE
;
157 pImpData
->pModule
= pMod
;
159 pMod
->GetSlotPool()->RegisterInterface(*this);
161 SFX_APP()->GetAppSlotPool_Impl().RegisterInterface(*this);
164 void SfxInterface::SetSlotMap( SfxSlot
& rSlotMap
, USHORT nSlotCount
)
168 SfxSlot
* pIter
= pSlots
;
169 if ( 1 == nCount
&& !pIter
->pNextSlot
)
170 pIter
->pNextSlot
= pIter
;
172 if ( !pIter
->pNextSlot
)
174 // sort the SfxSlots by id
175 qsort( pSlots
, nCount
, sizeof(SfxSlot
), SfxCompareSlots_Impl
);
177 // link masters and slaves
179 for ( pIter
= pSlots
; nIter
<= nCount
; ++pIter
, ++nIter
)
181 //! hier bitte sinnvoll pruefen
182 //! DBG_ASSERT(!(pIter->IsMode(SFX_SLOT_CACHABLE) &&
183 //! pIter->IsMode(SFX_SLOT_VOLATILE)),
184 //! "invalid Flags" );
185 DBG_ASSERT( nIter
== nCount
||
186 pIter
->GetSlotId() != (pIter
+1)->GetSlotId(),
189 // jeder Master verweist auf seinen ersten Slave (ENUM), alle
190 // Slaves auf ihren Master.
191 // Slaves verweisen im Ring auf die anderen mit gleichem Master
192 if ( pIter
->GetKind() == SFX_KIND_ENUM
)
194 pIter
->pLinkedSlot
= GetSlot( pIter
->nMasterSlotId
);
195 DBG_ASSERT( pIter
->pLinkedSlot
, "slave without master" );
196 if ( !pIter
->pLinkedSlot
->pLinkedSlot
)
197 ( (SfxSlot
*) pIter
->pLinkedSlot
)->pLinkedSlot
= pIter
;
199 if ( 0 == pIter
->GetNextSlot() )
201 SfxSlot
*pLastSlot
= pIter
;
202 for ( USHORT n
= nIter
; n
< Count(); ++n
)
204 SfxSlot
*pCurSlot
= (pSlots
+n
);
205 if ( pCurSlot
->nMasterSlotId
== pIter
->nMasterSlotId
)
207 pLastSlot
->pNextSlot
= pCurSlot
;
208 pLastSlot
= pCurSlot
;
211 pLastSlot
->pNextSlot
= pIter
;
214 else if ( 0 == pIter
->GetNextSlot() )
216 // Slots verweisen im Ring auf den n"achten mit derselben Statusmethode
217 SfxSlot
*pLastSlot
= pIter
;
218 for ( USHORT n
= nIter
; n
< Count(); ++n
)
220 SfxSlot
*pCurSlot
= (pSlots
+n
);
221 if ( pCurSlot
->GetStateFnc() == pIter
->GetStateFnc() )
223 pLastSlot
->pNextSlot
= pCurSlot
;
224 pLastSlot
= pCurSlot
;
227 pLastSlot
->pNextSlot
= pIter
;
235 for ( SfxSlot
*pNext
= pIter
+1; nIter
< nCount
; ++pNext
, ++nIter
)
238 if ( pNext
->GetSlotId() <= pIter
->GetSlotId() )
239 DBG_ERROR ("Falsche Reihenfolge!");
241 if ( pIter
->GetKind() == SFX_KIND_ENUM
)
243 const SfxSlot
*pMasterSlot
= GetSlot(pIter
->nMasterSlotId
);
244 const SfxSlot
*pFirstSlave
= pMasterSlot
->pLinkedSlot
;
245 const SfxSlot
*pSlave
= pFirstSlave
;
248 if ( pSlave
->pLinkedSlot
!= pMasterSlot
)
250 ByteString
aStr("Falsche Master/Slave-Verkettung : ");
251 aStr
+= ByteString::CreateFromInt32(pMasterSlot
->GetSlotId());
253 aStr
+= ByteString::CreateFromInt32(pSlave
->GetSlotId());
254 DBG_ERROR(aStr
.GetBuffer());
257 if ( pSlave
->nMasterSlotId
!= pMasterSlot
->GetSlotId() )
259 ByteString
aStr("Falsche Master/Slave-Ids : ");
260 aStr
+= ByteString::CreateFromInt32(pMasterSlot
->GetSlotId());
262 aStr
+= ByteString::CreateFromInt32(pSlave
->GetSlotId());
263 DBG_ERROR(aStr
.GetBuffer());
266 pSlave
= pSlave
->pNextSlot
;
268 while ( pSlave
!= pFirstSlave
);
272 if ( pIter
->pLinkedSlot
)
274 if ( pIter
->pLinkedSlot
->GetKind() != SFX_KIND_ENUM
)
276 ByteString
aStr("Slave ist kein enum : ");
277 aStr
+= ByteString::CreateFromInt32(pIter
->GetSlotId());
279 aStr
+= ByteString::CreateFromInt32(pIter
->pLinkedSlot
->GetSlotId());
280 DBG_ERROR(aStr
.GetBuffer());
284 const SfxSlot
*pCurSlot
= pIter
;
287 pCurSlot
= pCurSlot
->pNextSlot
;
288 if ( pCurSlot
->GetStateFnc() != pIter
->GetStateFnc() )
290 ByteString
aStr("Verkettete Slots mit verschiedenen StateMethods : ");
291 aStr
+= ByteString::CreateFromInt32(pCurSlot
->GetSlotId());
293 aStr
+= ByteString::CreateFromInt32(pIter
->GetSlotId());
294 DBG_ERROR(aStr
.GetBuffer());
297 while ( pCurSlot
!= pIter
);
307 //--------------------------------------------------------------------
311 SfxInterface::~SfxInterface()
313 SfxModule
*pMod
= pImpData
->pModule
;
314 BOOL bRegistered
= pImpData
->bRegistered
;
316 DBG_ASSERT( bRegistered
, "Interface not registered!" );
320 pMod
->GetSlotPool()->ReleaseInterface(*this);
322 SFX_APP()->GetAppSlotPool_Impl().ReleaseInterface(*this);
326 //--------------------------------------------------------------------
328 // searches for the specified func
331 const SfxSlot
* SfxInterface::GetSlot( USHORT nFuncId
) const
334 DBG_CHKTHIS(SfxInterface
, 0);
335 DBG_ASSERT( this && pSlots
&& nCount
, "" );
337 // find the id using binary search
338 void* p
= bsearch( &nFuncId
, pSlots
, nCount
, sizeof(SfxSlot
),
339 SfxCompareSlots_Impl
);
340 if ( !p
&& pGenoType
)
341 return pGenoType
->GetSlot( nFuncId
);
343 return p
? (const SfxSlot
*)p
: 0;
346 const SfxSlot
* SfxInterface::GetSlot( const String
& rCommand
) const
348 static const char UNO_COMMAND
[] = ".uno:";
350 String
aCommand( rCommand
);
351 if ( aCommand
.SearchAscii( UNO_COMMAND
) == 0 )
352 aCommand
.Erase( 0, sizeof( UNO_COMMAND
)-1 );
354 for ( USHORT n
=0; n
<nCount
; n
++ )
356 if ( (pSlots
+n
)->pUnoName
&&
357 aCommand
.CompareIgnoreCaseToAscii( (pSlots
+n
)->GetUnoName() ) == COMPARE_EQUAL
)
361 return pGenoType
? pGenoType
->GetSlot( aCommand
) : NULL
;
364 //--------------------------------------------------------------------
367 const SfxSlot
* SfxInterface::GetRealSlot( const SfxSlot
*pSlot
) const
370 DBG_CHKTHIS(SfxInterface
, 0);
371 DBG_ASSERT( this && pSlots
&& nCount
, "" );
373 if ( !ContainsSlot_Impl(pSlot
) )
376 return pGenoType
->GetRealSlot(pSlot
);
377 DBG_ERROR("fremder Slot");
381 return pSlot
->pLinkedSlot
;
384 //--------------------------------------------------------------------
387 const SfxSlot
* SfxInterface::GetRealSlot( USHORT nSlotId
) const
390 DBG_CHKTHIS(SfxInterface
, 0);
391 DBG_ASSERT( this && pSlots
&& nCount
, "" );
393 const SfxSlot
*pSlot
= GetSlot(nSlotId
);
397 return pGenoType
->GetRealSlot(nSlotId
);
398 DBG_ERROR("fremder Slot");
402 return pSlot
->pLinkedSlot
;
405 //--------------------------------------------------------------------
408 void SfxInterface::RegisterPopupMenu( const ResId
& rResId
)
410 DBG_CHKTHIS(SfxInterface
, 0);
411 pImpData
->aPopupRes
= rResId
;
414 //--------------------------------------------------------------------
416 void SfxInterface::RegisterObjectBar( USHORT nPos
, const ResId
& rResId
,
419 RegisterObjectBar( nPos
, rResId
, 0UL, pStr
);
423 void SfxInterface::RegisterObjectBar( USHORT nPos
, const ResId
& rResId
, sal_uInt32 nFeature
, const String
*pStr
)
425 SfxObjectUI_Impl
* pUI
= CreateObjectBarUI_Impl( nPos
, rResId
, nFeature
, pStr
);
427 pImpData
->pObjectBars
->Append(pUI
);
430 SfxObjectUI_Impl
* CreateObjectBarUI_Impl( USHORT nPos
, const ResId
& rResId
, sal_uInt32 nFeature
, const String
*pStr
)
432 if ((nPos
& SFX_VISIBILITY_MASK
) == 0)
433 nPos
|= SFX_VISIBILITY_STANDARD
;
435 SfxObjectUI_Impl
* pUI
= new SfxObjectUI_Impl(nPos
, rResId
, TRUE
, nFeature
);
439 ResId
aResId(rResId
);
440 aResId
.SetRT(RSC_STRING
);
441 aResId
.SetResMgr(rResId
.GetResMgr());
442 if( ! aResId
.GetResMgr() )
443 aResId
.SetResMgr( SfxApplication::GetOrCreate()->GetOffResManager_Impl() );
444 if ( !aResId
.GetResMgr()->IsAvailable(aResId
) )
445 pUI
->pName
= new String (DEFINE_CONST_UNICODE("NoName"));
447 pUI
->pName
= new String(aResId
);
450 pUI
->pName
= new String(*pStr
);
455 const ResId
& SfxInterface::GetObjectBarResId( USHORT nNo
) const
457 BOOL bGenoType
= (pGenoType
!= 0 && !pGenoType
->HasName());
460 // Gibt es Toolbars in der Superklasse ?
461 USHORT nBaseCount
= pGenoType
->GetObjectBarCount();
462 if ( nNo
< nBaseCount
)
463 // Die der Superklasse kommen zuerst
464 return pGenoType
->GetObjectBarResId( nNo
);
466 nNo
= nNo
- nBaseCount
;
470 USHORT nObjBarCount
= pImpData
->pObjectBars
->Count();
471 DBG_ASSERT( nNo
<nObjBarCount
,"Objectbar ist unbekannt!" );
473 return (*pImpData
->pObjectBars
)[nNo
]->aResId
;
476 //--------------------------------------------------------------------
479 USHORT
SfxInterface::GetObjectBarPos( USHORT nNo
) const
481 BOOL bGenoType
= (pGenoType
!= 0 && !pGenoType
->HasName());
484 // Gibt es Toolbars in der Superklasse ?
485 USHORT nBaseCount
= pGenoType
->GetObjectBarCount();
486 if ( nNo
< nBaseCount
)
487 // Die der Superklasse kommen zuerst
488 return pGenoType
->GetObjectBarPos( nNo
);
490 nNo
= nNo
- nBaseCount
;
494 USHORT nObjBarCount
= pImpData
->pObjectBars
->Count();
495 DBG_ASSERT( nNo
<nObjBarCount
,"Objectbar ist unbekannt!" );
497 return (*pImpData
->pObjectBars
)[nNo
]->nPos
;
500 //--------------------------------------------------------------------
503 USHORT
SfxInterface::GetObjectBarCount() const
505 if (pGenoType
&& ! pGenoType
->HasName())
506 return pImpData
->pObjectBars
->Count() + pGenoType
->GetObjectBarCount();
508 return pImpData
->pObjectBars
->Count();
511 //--------------------------------------------------------------------
512 void SfxInterface::RegisterChildWindow(USHORT nId
, BOOL bContext
, const String
* pChildWinName
)
514 RegisterChildWindow( nId
, bContext
, 0UL, pChildWinName
);
517 void SfxInterface::RegisterChildWindow(USHORT nId
, BOOL bContext
, sal_uInt32 nFeature
, const String
*)
519 SfxObjectUI_Impl
* pUI
= new SfxObjectUI_Impl(0, ResId(nId
, *SfxApplication::GetOrCreate()->GetOffResManager_Impl()), TRUE
, nFeature
);
520 pUI
->bContext
= bContext
;
521 pImpData
->pChildWindows
->Append(pUI
);
524 void SfxInterface::RegisterStatusBar(const ResId
& rResId
)
526 pImpData
->aStatBarRes
= rResId
;
530 sal_uInt32
SfxInterface::GetChildWindowId (USHORT nNo
) const
534 // Gibt es ChildWindows in der Superklasse ?
535 USHORT nBaseCount
= pGenoType
->GetChildWindowCount();
536 if ( nNo
< nBaseCount
)
537 // Die der Superklasse kommen zuerst
538 return pGenoType
->GetChildWindowId( nNo
);
540 nNo
= nNo
- nBaseCount
;
544 USHORT nCWCount
= pImpData
->pChildWindows
->Count();
545 DBG_ASSERT( nNo
<nCWCount
,"ChildWindow ist unbekannt!" );
547 sal_uInt32 nRet
= (*pImpData
->pChildWindows
)[nNo
]->aResId
.GetId();
548 if ( (*pImpData
->pChildWindows
)[nNo
]->bContext
)
549 nRet
+= sal_uInt32( nClassId
) << 16;
553 sal_uInt32
SfxInterface::GetChildWindowFeature (USHORT nNo
) const
557 // Gibt es ChildWindows in der Superklasse ?
558 USHORT nBaseCount
= pGenoType
->GetChildWindowCount();
559 if ( nNo
< nBaseCount
)
560 // Die der Superklasse kommen zuerst
561 return pGenoType
->GetChildWindowFeature( nNo
);
563 nNo
= nNo
- nBaseCount
;
567 USHORT nCWCount
= pImpData
->pChildWindows
->Count();
568 DBG_ASSERT( nNo
<nCWCount
,"ChildWindow ist unbekannt!" );
570 return (*pImpData
->pChildWindows
)[nNo
]->nFeature
;
573 //--------------------------------------------------------------------
576 USHORT
SfxInterface::GetChildWindowCount() const
579 return pImpData
->pChildWindows
->Count() + pGenoType
->GetChildWindowCount();
581 return pImpData
->pChildWindows
->Count();
585 const ResId
& SfxInterface::GetPopupMenuResId() const
587 return pImpData
->aPopupRes
;
591 const ResId
& SfxInterface::GetStatusBarResId() const
593 if (pImpData
->aStatBarRes
.GetId() == 0 && pGenoType
)
594 return pGenoType
->GetStatusBarResId();
596 return pImpData
->aStatBarRes
;
601 const String
* SfxInterface::GetObjectBarName ( USHORT nNo
) const
603 BOOL bGenoType
= (pGenoType
!= 0 && !pGenoType
->HasName());
606 // Gibt es Toolbars in der Superklasse ?
607 USHORT nBaseCount
= pGenoType
->GetObjectBarCount();
608 if ( nNo
< nBaseCount
)
609 // Die der Superklasse kommen zuerst
610 return pGenoType
->GetObjectBarName( nNo
);
612 nNo
= nNo
- nBaseCount
;
616 USHORT nObjBarCount
= pImpData
->pObjectBars
->Count();
617 DBG_ASSERT( nNo
<nObjBarCount
,"Objectbar ist unbekannt!" );
619 return (*pImpData
->pObjectBars
)[nNo
]->pName
;
622 sal_uInt32
SfxInterface::GetObjectBarFeature ( USHORT nNo
) const
624 BOOL bGenoType
= (pGenoType
!= 0 && !pGenoType
->HasName());
627 // Gibt es Toolbars in der Superklasse ?
628 USHORT nBaseCount
= pGenoType
->GetObjectBarCount();
629 if ( nNo
< nBaseCount
)
630 // Die der Superklasse kommen zuerst
631 return pGenoType
->GetObjectBarFeature( nNo
);
633 nNo
= nNo
- nBaseCount
;
637 USHORT nObjBarCount
= pImpData
->pObjectBars
->Count();
638 DBG_ASSERT( nNo
<nObjBarCount
,"Objectbar ist unbekannt!" );
640 return (*pImpData
->pObjectBars
)[nNo
]->nFeature
;
643 BOOL
SfxInterface::IsObjectBarVisible(USHORT nNo
) const
645 BOOL bGenoType
= (pGenoType
!= 0 && !pGenoType
->HasName());
648 // Gibt es Toolbars in der Superklasse ?
649 USHORT nBaseCount
= pGenoType
->GetObjectBarCount();
650 if ( nNo
< nBaseCount
)
651 // Die der Superklasse kommen zuerst
652 return pGenoType
->IsObjectBarVisible( nNo
);
654 nNo
= nNo
- nBaseCount
;
658 USHORT nObjBarCount
= pImpData
->pObjectBars
->Count();
659 DBG_ASSERT( nNo
<nObjBarCount
,"Objectbar ist unbekannt!" );
661 return (*pImpData
->pObjectBars
)[nNo
]->bVisible
;
664 const SfxInterface
* SfxInterface::GetRealInterfaceForSlot( const SfxSlot
*pRealSlot
) const
666 DBG_ASSERT( pImpData
->bRegistered
, "Interface not registered!" );
667 const SfxInterface
* pInterface
= this;
669 // Der Slot k"onnte auch aus dem Interface einer Shell-Basisklasse stammen
672 const SfxSlot
*pLastSlot
= (*pInterface
)[pInterface
->Count()-1];
673 const SfxSlot
*pFirstSlot
= (*pInterface
)[0];
675 // Ist pInterface der Owner von pRealSlot ?
676 if ( pFirstSlot
<= pRealSlot
&& pRealSlot
<= pLastSlot
)
679 // Sonst Interface der Superklasse probieren
680 pInterface
= pInterface
->pGenoType
;
682 while ( pInterface
);