bump product version to 4.2.0.1
[LibreOffice.git] / sfx2 / source / control / objface.cxx
blob2778b393a6a085a8e595306727455de8b450a104
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
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 .
21 #include <stdlib.h>
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 //====================================================================
38 extern "C"
39 #ifdef WNT
40 int _cdecl
41 #else
42 int
43 #endif
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
55 sal_uInt16 nPos;
56 ResId aResId;
57 sal_Bool bVisible;
58 sal_Bool bContext;
59 OUString* pName;
60 sal_uInt32 nFeature;
62 SfxObjectUI_Impl(sal_uInt16 n, const ResId& rResId, sal_Bool bVis, sal_uInt32 nFeat) :
63 nPos(n),
64 aResId(rResId.GetId(), *rResId.GetResMgr()),
65 bVisible(bVis),
66 bContext(sal_False),
67 pName(0),
68 nFeature(nFeat)
70 aResId.SetRT(rResId.GetRT());
73 ~SfxObjectUI_Impl()
75 delete pName;
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
87 SfxModule* pModule;
88 sal_Bool bRegistered;
90 SfxInterface_Impl() :
91 aPopupRes(0,*SfxApplication::GetOrCreate()->GetSfxResManager()),
92 aStatBarRes(0,*SfxApplication::GetOrCreate()->GetSfxResManager())
93 , pModule(NULL)
94 , bRegistered(sal_False)
98 ~SfxInterface_Impl()
100 for (SfxObjectUIArr_Impl::const_iterator it = aObjectBars.begin(); it != aObjectBars.end(); ++it)
101 delete *it;
103 for (SfxObjectUIArr_Impl::const_iterator it = aChildWindows.begin(); it != aChildWindows.end(); ++it)
104 delete *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,
117 SfxInterfaceId nId,
118 const SfxInterface* pParent,
119 SfxSlot &rSlotMap, sal_uInt16 nSlotCount ):
120 pName(pClassName),
121 pGenoType(pParent),
122 nClassId(nId),
123 aNameResId(rNameResId.GetId(),*rNameResId.GetResMgr()),
124 pImpData(0)
126 pImpData = new SfxInterface_Impl;
127 SetSlotMap( rSlotMap, nSlotCount );
130 void SfxInterface::Register( SfxModule* pMod )
132 pImpData->bRegistered = sal_True;
133 pImpData->pModule = pMod;
134 if ( pMod )
135 pMod->GetSlotPool()->RegisterInterface(*this);
136 else
137 SFX_APP()->GetAppSlotPool_Impl().RegisterInterface(*this);
140 void SfxInterface::SetSlotMap( SfxSlot& rSlotMap, sal_uInt16 nSlotCount )
142 pSlots = &rSlotMap;
143 nCount = 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(),
160 "doppelte SID" );
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
190 // Status method.
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;
205 #ifdef DBG_UTIL
206 else
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()));
227 aStr.append(" , ");
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()));
238 aStr.append(" , ");
239 aStr.append(static_cast<sal_Int32>(
240 pSlave->GetSlotId()));
241 OSL_FAIL(aStr.getStr());
244 pSlave = pSlave->pNextSlot;
246 while ( pSlave != pFirstSlave );
248 else
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()));
256 aStr.append(" , ");
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()));
272 aStr.append(" , ");
273 aStr.append(static_cast<sal_Int32>(pIter->GetSlotId()));
274 OSL_FAIL(aStr.getStr());
277 while ( pCurSlot != pIter );
280 pIter = pNext;
283 #endif
286 //--------------------------------------------------------------------
288 SfxInterface::~SfxInterface()
290 SfxModule *pMod = pImpData->pModule;
291 sal_Bool bRegistered = pImpData->bRegistered;
292 delete pImpData;
293 DBG_ASSERT( bRegistered, "Interface not registered!" );
294 if ( bRegistered )
296 if ( pMod )
297 pMod->GetSlotPool()->ReleaseInterface(*this);
298 else
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 )
333 return pSlots+n;
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) )
348 if(pGenoType)
349 return pGenoType->GetRealSlot(pSlot);
350 OSL_FAIL("unknown Slot");
351 return 0;
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);
365 if ( !pSlot )
367 if(pGenoType)
368 return pGenoType->GetRealSlot(nSlotId);
369 OSL_FAIL("unkonown Slot");
370 return 0;
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 );
396 if ( pUI )
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);
407 if (pStr == 0)
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");
416 else
417 pUI->pName = new OUString(aResId.toString());
419 else
420 pUI->pName = new OUString(*pStr);
422 return pUI;
425 const ResId& SfxInterface::GetObjectBarResId( sal_uInt16 nNo ) const
427 sal_Bool bGenoType = (pGenoType != 0 && !pGenoType->HasName());
428 if ( bGenoType )
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 );
435 else
436 nNo = nNo - nBaseCount;
439 #ifdef DBG_UTIL
440 sal_uInt16 nObjBarCount = pImpData->aObjectBars.size();
441 DBG_ASSERT( nNo<nObjBarCount,"Objectbar is unknown!" );
442 #endif
443 return pImpData->aObjectBars[nNo]->aResId;
446 //--------------------------------------------------------------------
449 sal_uInt16 SfxInterface::GetObjectBarPos( sal_uInt16 nNo ) const
451 sal_Bool bGenoType = (pGenoType != 0 && !pGenoType->HasName());
452 if ( bGenoType )
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 );
459 else
460 nNo = nNo - nBaseCount;
463 #ifdef DBG_UTIL
464 sal_uInt16 nObjBarCount = pImpData->aObjectBars.size();
465 DBG_ASSERT( nNo<nObjBarCount,"Objectbar is unknown!" );
466 #endif
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();
477 else
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
502 if ( pGenoType )
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 );
509 else
510 nNo = nNo - nBaseCount;
513 #ifdef DBG_UTIL
514 sal_uInt16 nCWCount = pImpData->aChildWindows.size();
515 DBG_ASSERT( nNo<nCWCount,"ChildWindow is unknown!" );
516 #endif
517 sal_uInt32 nRet = pImpData->aChildWindows[nNo]->aResId.GetId();
518 if ( pImpData->aChildWindows[nNo]->bContext )
519 nRet += sal_uInt32( nClassId ) << 16;
520 return nRet;
523 sal_uInt32 SfxInterface::GetChildWindowFeature (sal_uInt16 nNo) const
525 if ( pGenoType )
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 );
532 else
533 nNo = nNo - nBaseCount;
536 #ifdef DBG_UTIL
537 sal_uInt16 nCWCount = pImpData->aChildWindows.size();
538 DBG_ASSERT( nNo<nCWCount,"ChildWindow is unknown!" );
539 #endif
540 return pImpData->aChildWindows[nNo]->nFeature;
543 //--------------------------------------------------------------------
546 sal_uInt16 SfxInterface::GetChildWindowCount() const
548 if (pGenoType)
549 return pImpData->aChildWindows.size() + pGenoType->GetChildWindowCount();
550 else
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();
565 else
566 return pImpData->aStatBarRes;
571 const OUString* SfxInterface::GetObjectBarName ( sal_uInt16 nNo ) const
573 sal_Bool bGenoType = (pGenoType != 0 && !pGenoType->HasName());
574 if ( bGenoType )
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 );
581 else
582 nNo = nNo - nBaseCount;
585 #ifdef DBG_UTIL
586 sal_uInt16 nObjBarCount = pImpData->aObjectBars.size();
587 DBG_ASSERT( nNo<nObjBarCount,"Objectbar is unknown!" );
588 #endif
589 return pImpData->aObjectBars[nNo]->pName;
592 sal_uInt32 SfxInterface::GetObjectBarFeature ( sal_uInt16 nNo ) const
594 sal_Bool bGenoType = (pGenoType != 0 && !pGenoType->HasName());
595 if ( bGenoType )
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 );
602 else
603 nNo = nNo - nBaseCount;
606 #ifdef DBG_UTIL
607 sal_uInt16 nObjBarCount = pImpData->aObjectBars.size();
608 DBG_ASSERT( nNo<nObjBarCount,"Objectbar is unknown!" );
609 #endif
610 return pImpData->aObjectBars[nNo]->nFeature;
613 sal_Bool SfxInterface::IsObjectBarVisible(sal_uInt16 nNo) const
615 sal_Bool bGenoType = (pGenoType != 0 && !pGenoType->HasName());
616 if ( bGenoType )
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 );
623 else
624 nNo = nNo - nBaseCount;
627 #ifdef DBG_UTIL
628 sal_uInt16 nObjBarCount = pImpData->aObjectBars.size();
629 DBG_ASSERT( nNo<nObjBarCount,"Objectbar is unknown!" );
630 #endif
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 )
647 break;
649 // Otherwise try the Interface of Super class
650 pInterface = pInterface->pGenoType;
652 while ( pInterface );
654 return pInterface;
657 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */