/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /************************************************************************* * * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * Copyright 2000, 2010 Oracle and/or its affiliates. * * OpenOffice.org - a multi-platform office productivity suite * * This file is part of OpenOffice.org. * * OpenOffice.org is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 3 * only, as published by the Free Software Foundation. * * OpenOffice.org is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License version 3 for more details * (a copy is included in the LICENSE file that accompanied this code). * * You should have received a copy of the GNU Lesser General Public License * version 3 along with OpenOffice.org. If not, see * * for a copy of the LGPLv3 License. * ************************************************************************/ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "sfxtypes.hxx" #include #include #include "statcach.hxx" #include //==================================================================== DBG_NAME(SfxShell) //==================================================================== TYPEINIT0(SfxShell); //==================================================================== typedef SfxSlot* SfxSlotPtr; SV_DECL_PTRARR_DEL( SfxVerbSlotArr_Impl, SfxSlotPtr, 4 ) SV_IMPL_PTRARR( SfxVerbSlotArr_Impl, SfxSlotPtr); using namespace com::sun::star; //========================================================================= // SfxShell_Impl //========================================================================= struct SfxShell_Impl: public SfxBroadcaster { String aObjectName; // Name of Sbx-Objects SfxItemArray_Impl aItems; // Data exchange on Item level SfxViewShell* pViewSh; // SfxViewShell if Shell is // ViewFrame/ViewShell/SubShell list SfxViewFrame* pFrame; // Frame, if SfxRepeatTarget* pRepeatTarget; // SbxObjectRef xParent; sal_Bool bInAppBASIC; sal_Bool bActive; sal_uIntPtr nDisableFlags; sal_uIntPtr nHelpId; svtools::AsynchronLink* pExecuter; svtools::AsynchronLink* pUpdater; SfxVerbSlotArr_Impl aSlotArr; com::sun::star::uno::Sequence < com::sun::star::embed::VerbDescriptor > aVerbList; SfxShell_Impl() : pExecuter( 0 ), pUpdater( 0 ) {} ~SfxShell_Impl() { delete pExecuter; delete pUpdater;} }; //========================================================================= // SfxShell //========================================================================= void SfxShell::EmptyExecStub(SfxShell *, SfxRequest &) { } void SfxShell::EmptyStateStub(SfxShell *, SfxItemSet &) { } SfxShell::SfxShell() /* [Description] The constructor of the SfxShell class initializes only simple types, the corresponding SbxObject is only created on-demand. Therefore, the application of a SfxShell instance is very cheap. */ : pImp(0), pPool(0), pUndoMgr(0) { DBG_CTOR(SfxShell, 0); pImp = new SfxShell_Impl; pImp->pViewSh = 0; pImp->pFrame = 0; pImp->pRepeatTarget = 0; pImp->bInAppBASIC = sal_False; pImp->nHelpId = 0L; pImp->bActive = sal_False; pImp->nDisableFlags = 0; } //------------------------------------------------------------------------- SfxShell::SfxShell( SfxViewShell *pViewSh ) /* [Description] The constructor of the SfxShell class initializes only simple types, the corresponding SbxObject is only created on-demand. Therefore, the application of a SfxShell instance is very cheap. */ : pImp(0), pPool(0), pUndoMgr(0) { DBG_CTOR(SfxShell, 0); pImp = new SfxShell_Impl; pImp->pViewSh = pViewSh; pImp->pFrame = 0; pImp->pRepeatTarget = 0; pImp->bInAppBASIC = sal_False; pImp->nHelpId = 0L; pImp->bActive = sal_False; } //-------------------------------------------------------------------- SfxShell::~SfxShell() /* [Description] The connection to a possible corresponding SbxObject is dissolved. The SbxObject may continoue to exist, but can not any longer perform any functions and can not provide any properties. */ { DBG_DTOR(SfxShell, 0); delete pImp; } //-------------------------------------------------------------------- void SfxShell::SetName( const String &rName ) /* [Description] Sets the name of the Shell object. With this name, the SfxShell instance of BASIC can be expressed. */ { pImp->aObjectName = rName; } //-------------------------------------------------------------------- const String& SfxShell::GetName() const /* [Description] Returns the name of the Shell object. With this name, the SfxShell instance of BASIC can be expressed. */ { return pImp->aObjectName; } //-------------------------------------------------------------------- SvGlobalName SfxShell::GetGlobalName() const /* [Description] Provides the Global Unique Identifier of the Shell object. With this name can the SfxShell instance for example be expressed via OLE Automation, or be found in the Registration Database. */ { return SvGlobalName(); } //-------------------------------------------------------------------- SfxDispatcher* SfxShell::GetDispatcher() const /* [Description] This method returns a pointer to the , when the SfxShell is currently or a NULL-pointer if it is not UI-active. The returned pointer is only valid in the immediate context of the method call. */ { return pImp->pFrame ? pImp->pFrame->GetDispatcher() : 0; } //-------------------------------------------------------------------- SfxViewShell* SfxShell::GetViewShell() const /* [Description] Returns the SfxViewShell in which they are located in the subshells. Otherwise, and if not specified by the App developer, this method returns NULL. */ { return pImp->pViewSh; } //-------------------------------------------------------------------- SfxViewFrame* SfxShell::GetFrame() const /* [Description] This method returns a pointer to the to which this SfxShell instance is associated or in which they currently is . A NULL pointer is returned if this SfxShell instance is not UI-active at the moment and also no SfxViewFrame is permanently assigned. The returned pointer is only valid in the immediate context of the method call. [Note] Only instances of a subclass of SfxApplication and SfxObjectShell should here provide a NULL-pointer. Otherwise, there is an error in the application program (wrong constructor was called from SfxShell). [Cross-reference] */ { if ( pImp->pFrame ) return pImp->pFrame; if ( pImp->pViewSh ) return pImp->pViewSh->GetViewFrame(); return 0; } //-------------------------------------------------------------------- const SfxPoolItem* SfxShell::GetItem ( sal_uInt16 nSlotId // Slot-Id of the querying s ) const /* [Description] With this method any objects of subclasses can be accessed. This exchange method is needed if, for example special subclasses need access to certain data such as the . The returned instance belongs to the particular SfxShell and may be used only in the immediate context of the method call. [Cross-reference] */ { for ( sal_uInt16 nPos = 0; nPos < pImp->aItems.Count(); ++nPos ) if ( pImp->aItems.GetObject(nPos)->Which() == nSlotId ) return pImp->aItems.GetObject(nPos); return 0; } //-------------------------------------------------------------------- void SfxShell::PutItem ( const SfxPoolItem& rItem /* Instance, of which a copy is created, which is stored in the SfxShell in a list. */ ) /* [Description] With this method, any objects of subclasses of can be made available. This exchange technology is needed if, for example, special Subclasses need access to certain data such as the If a SfxPoolItem exists with the same slot ID, it is deleted automatically. [Cross-reference] */ { DBG_ASSERT( !rItem.ISA(SfxSetItem), "SetItems aren't allowed here" ); DBG_ASSERT( SfxItemPool::IsSlot( rItem.Which() ), "items with Which-Ids aren't allowed here" ); // MSC made a mess here of WNT/W95, beware of changes const SfxPoolItem *pItem = rItem.Clone(); SfxPoolItemHint aItemHint( (SfxPoolItem*) pItem ); const sal_uInt16 nWhich = rItem.Which(); SfxPoolItem **ppLoopItem = (SfxPoolItem**) pImp->aItems.GetData(); sal_uInt16 nPos; for ( nPos = 0; nPos < pImp->aItems.Count(); ++nPos, ++ppLoopItem ) { if ( (*ppLoopItem)->Which() == nWhich ) { // Replace Item delete *ppLoopItem; pImp->aItems.Remove(nPos); pImp->aItems.Insert( (SfxPoolItemPtr) pItem, nPos ); // if active, notify Bindings SfxDispatcher *pDispat = GetDispatcher(); if ( pDispat ) { SfxBindings* pBindings = pDispat->GetBindings(); pBindings->Broadcast( aItemHint ); sal_uInt16 nSlotId = nWhich; //pItem->GetSlotId(); SfxStateCache* pCache = pBindings->GetStateCache( nSlotId ); if ( pCache ) { pCache->SetState( SFX_ITEM_AVAILABLE, pItem->Clone(), sal_True ); pCache->SetCachedState( sal_True ); } } return; } } Broadcast( aItemHint ); pImp->aItems.Insert((SfxPoolItemPtr)pItem, nPos ); } //-------------------------------------------------------------------- SfxInterface* SfxShell::GetInterface() const /* [Description] With this virtual method, which is automatically overloaded by each subclass with its own slots through the macro , one can access each of the instance beloning to the subclass. The class SfxShell itself has no own SfxInterface (no slots), therefore a NULL-pointer is returned. */ { return GetStaticInterface(); } //-------------------------------------------------------------------- ::svl::IUndoManager* SfxShell::GetUndoManager() /* [Description] Each Subclass of SfxShell can hava a . This can be set in the derived class with . The class SfxShell itself does not have a SfxUndoManager, a NULL-pointer is therefore returned. */ { return pUndoMgr; } //-------------------------------------------------------------------- void SfxShell::SetUndoManager( ::svl::IUndoManager *pNewUndoMgr ) /* [Description] Sets a for this Instance. For the undo is only the undo-manager used for SfxShell at the top of the stack of each . On the given is automatically the current Max-Undo-Action-Count setting set form the options. 'pNewUndoMgr' must exist until the Destuctor of SfxShell instance is called or until the next 'SetUndoManager()'. */ { OSL_ENSURE( ( pUndoMgr == NULL ) || ( pNewUndoMgr == NULL ) || ( pUndoMgr == pNewUndoMgr ), "SfxShell::SetUndoManager: exchanging one non-NULL manager with another non-NULL manager? Suspicious!" ); // there's at least one client of our UndoManager - the DocumentUndoManager at the SfxBaseModel - which // caches the UndoManager, and registers itself as listener. If exchanging non-NULL UndoManagers is really // a supported scenario (/me thinks it is not), then we would need to notify all such clients instances. pUndoMgr = pNewUndoMgr; if ( pUndoMgr ) pUndoMgr->SetMaxUndoActionCount( officecfg::Office::Common::Undo::Steps::get()); } //-------------------------------------------------------------------- SfxRepeatTarget* SfxShell::GetRepeatTarget() const /* [Description] Returns a pointer to the instance that is used in SID_REPEAT as repeat target when it is addressed from the supplied by this SfxShell. The return value can be NULL. [Note] A derivation of or one of its subclasses of is not recommended, as compiler errors are provoked. (due to Call-to-Pointer-to-Member-Function to the subclass). */ { return pImp->pRepeatTarget; } //-------------------------------------------------------------------- void SfxShell::SetRepeatTarget( SfxRepeatTarget *pTarget ) /* [Description] Sets the instance that is used in SID_REPEAT as RepeatTarget, when the current supplied by this is addressed. By 'pTarget==0' the SID_REPEAT is disabled for this SfxShell. The instance '*pTarget' must live as long as it is registered. [Note] A derivation of or one of its subclasses of is not recommended, as compiler errors are provoked. (due to Call-to-Pointer-to-Member-Function to the subclass). */ { pImp->pRepeatTarget = pTarget; } //-------------------------------------------------------------------- void SfxShell::Invalidate ( sal_uInt16 nId /* Invalidated Slot-Id or Which-Id. If these are 0 (default), then all by this Shell currently handled Slot-Ids are invalidated. */ ) /* [Description] With this method can the slots of the subclasses be invalidated through the slot Id or alternatively through the Which ID. Slot IDs, which are inherited by the subclass are also invalidert. [Cross-reference] */ { if ( !GetViewShell() ) { OSL_FAIL( "wrong Invalidate method called!" ); return; } Invalidate_Impl( GetViewShell()->GetViewFrame()->GetBindings(), nId ); } void SfxShell::Invalidate_Impl( SfxBindings& rBindings, sal_uInt16 nId ) { if ( nId == 0 ) { rBindings.InvalidateShell( *this, sal_False ); } else { const SfxInterface *pIF = GetInterface(); do { const SfxSlot *pSlot = pIF->GetSlot(nId); if ( pSlot ) { // At Enum-Slots invalidate the Master-Slot if ( SFX_KIND_ENUM == pSlot->GetKind() ) pSlot = pSlot->GetLinkedSlot(); // Invalidate the Slot itself and possible also all Slave-Slots rBindings.Invalidate( pSlot->GetSlotId() ); for ( const SfxSlot *pSlave = pSlot->GetLinkedSlot(); pSlave && pIF->ContainsSlot_Impl( pSlave ) && pSlave->GetLinkedSlot() == pSlot; ++pSlave ) rBindings.Invalidate( pSlave->GetSlotId() ); return; } pIF = pIF->GetGenoType(); } while ( pIF ); DBG_WARNING( "W3: invalidating slot-id unknown in shell" ); } } //-------------------------------------------------------------------- void SfxShell::DoActivate_Impl( SfxViewFrame *pFrame, sal_Bool bMDI ) /* [Description] This method controls the activation of SfxShell instance. First, by calling the virtual method which gives the subclass the opportunity to respond to the event. When bMDI == TRUE, the associated SbxObject is being 'armed', so that unqualified methods of the object (without the name of the object) from BASIC are found. */ { #ifdef DBG_UTIL const SfxInterface *p_IF = GetInterface(); if ( !p_IF ) return; #endif SAL_INFO( "sfx2.vb", "SfxShell::DoActivate() " << this << " " << GetInterface()->GetName() << " bMDI " << (bMDI ? "MDI" : "")); if ( bMDI ) { // Remember Frame, in which it was activated pImp->pFrame = pFrame; pImp->bActive = sal_True; } // Notify Subclass Activate(bMDI); } //-------------------------------------------------------------------- void SfxShell::DoDeactivate_Impl( SfxViewFrame *pFrame, sal_Bool bMDI ) /* [Description] This method controls the deactivation of the SfxShell instance. When bMDI == TRUE the SbxObject is first set to a status that only qualified BASIC methods can be called. Then the subclass gets the opportunity in every case to respond to the event by calling the virtual method . */ { #ifdef DBG_UTIL const SfxInterface *p_IF = GetInterface(); if ( !p_IF ) return; #endif SAL_INFO( "sfx2.vb", "SfxShell::DoDeactivate()" << this << " " << GetInterface()->GetName() << " bMDI " << (bMDI ? "MDI" : "")); // Only when it comes from a Frame // (not when for instance by poping BASIC-IDE from AppDisp) if ( bMDI && pImp->pFrame == pFrame ) { // deliver pImp->pFrame = 0; pImp->bActive = sal_False; } // Notify Subclass Deactivate(bMDI); } //-------------------------------------------------------------------- sal_Bool SfxShell::IsActive() const { return pImp->bActive; } //-------------------------------------------------------------------- void SfxShell::Activate ( sal_Bool /*bMDI*/ /* TRUE the , on which the SfxShell is located, is activated or the SfxShell instance was pushed on an active SfxDispatcher. (compare with SystemWindow::IsMDIActivate()) FALSE the , on which SfxDispatcher the SfxShell instance is located, was activated. (for example by a closing dialoge) */ ) /* [Description] Virtual method that is called when enabling the SfxShell instance, in order to give the Subclasses the opportunity to respond to the to the enabling. The base implementation is empty and does not need to be called. [Cross-reference] StarView SystemWindow::Activate(sal_Bool) */ { } //-------------------------------------------------------------------- void SfxShell::Deactivate ( sal_Bool /*bMDI*/ /* TRUE the , on which the SfxShell is located, is inactivated or the SfxShell instance was popped on an active SfxDispatcher. (compare with SystemWindow::IsMDIActivate()) FALSE the , on which SfxDispatcher the SfxShell instance is located, was deactivated. (for example by a dialoge) */ ) /* [Description] Virtual method that is called when disabling the SfxShell instance, to give the Subclasses the opportunity to respond to the disabling. The base implementation is empty and does not need to be called. [Cross-reference] StarView SystemWindow::Dectivate(sal_Bool) */ { } void SfxShell::ParentActivate ( ) /* [Description] A parent of the on which the SfxShell is located, has become active, or the SfxShell instance was pushed on a , which parent is active. The base implementation is empty and does not need to be called. [Cross-reference] SfxShell::Activate() */ { } //-------------------------------------------------------------------- void SfxShell::ParentDeactivate ( ) /* [Description] The active parent of the on which the SfxShell is located, has been disabled. The base implementation is empty and does not need to be called. [Cross-reference] SfxShell::Deactivate() */ { } //-------------------------------------------------------------------- ResMgr* SfxShell::GetResMgr() const /* [Description] This method provides the ResMgr of the that are used by the SfxShell instance. If this is a NULL-pointer, then the current resource manager is to be used. */ { return GetInterface()->GetResMgr(); } //-------------------------------------------------------------------- bool SfxShell::CanExecuteSlot_Impl( const SfxSlot &rSlot ) /* [Description] This method determines by calling the status function whether 'rSlot' can be executed currently. */ { // Get Slot status SfxItemPool &rPool = GetPool(); const sal_uInt16 nId = rSlot.GetWhich( rPool ); SfxItemSet aSet(rPool, nId, nId); SfxStateFunc pFunc = rSlot.GetStateFnc(); CallState( pFunc, aSet ); return aSet.GetItemState(nId) != SFX_ITEM_DISABLED; } //-------------------------------------------------------------------- long ShellCall_Impl( void* pObj, void* pArg ) { ((SfxShell* )pObj)->ExecuteSlot( *(SfxRequest*)pArg, (SfxInterface*)0L ); return 0; } /* [Description] Asynchronous ExecuteSlot for the RELOAD */ //-------------------------------------------------------------------- const SfxPoolItem* SfxShell::ExecuteSlot( SfxRequest& rReq, sal_Bool bAsync ) { if( !bAsync ) return ExecuteSlot( rReq, (SfxInterface*)0L ); else { if( !pImp->pExecuter ) pImp->pExecuter = new svtools::AsynchronLink( Link( this, ShellCall_Impl ) ); pImp->pExecuter->Call( new SfxRequest( rReq ) ); return 0; } } const SfxPoolItem* SfxShell::ExecuteSlot ( SfxRequest &rReq, // the relayed const SfxInterface* pIF // default = 0 means get virtually ) /* [Description] This method allows you to forward a to the specified base . [Example] In a derived class of SfxViewShell the SID_PRINTDOCDIRECT will be intercepted. Under certain circumstances a query should appear before you print, and the request will be aborted if necessary. Also in the IDL of this subclass of the above slot is entered. The status method will contain in outline: void SubViewShell::Exec( SfxRequest &rReq ) { if ( rReq.GetSlot() == SID_PRINTDOCDIRECT ) { 'dialog' if ( 'condition' ) ExecuteSlot( rReq, SfxViewShell::GetInterface() ); } } It usually takes no rReq.Done() to be called as that is already completed in implementation of the SfxViewShell, for instance it has been canceled. [Cross-reference] */ { if ( !pIF ) pIF = GetInterface(); sal_uInt16 nSlot = rReq.GetSlot(); const SfxSlot* pSlot = NULL; if ( nSlot >= SID_VERB_START && nSlot <= SID_VERB_END ) pSlot = GetVerbSlot_Impl(nSlot); if ( !pSlot ) pSlot = pIF->GetSlot(nSlot); DBG_ASSERT( pSlot, "slot not supported" ); SfxExecFunc pFunc = pSlot->GetExecFnc(); if ( pFunc ) CallExec( pFunc, rReq ); return rReq.GetReturnValue(); } //-------------------------------------------------------------------- const SfxPoolItem* SfxShell::GetSlotState ( sal_uInt16 nSlotId, // Slot-Id to the Slots in question const SfxInterface* pIF, // default = 0 means get virtually SfxItemSet* pStateSet // SfxItemSet of the Slot-State method ) /* [Description] This method returns the status of the slot with the specified slot ID on the specified interface. If the slot is disabled or in this SfxShell (and their parent shells) are not known, a Null-pointer is returned. If the slot does not have a Status, a SfxVoidItem is returned. The status is set directly in this Set when pStateSet != 0 , so that overloaded Slots of the Subclasses and also in the Status method of the base implementation can be called. [Example] In a derived class of SfxViewShell the SID_PRINTDOCDIRECT will be intercepted. Under certain circumstances a query should appear before you print, and the request will be aborted if necessary. Also in the IDL of this subclass of the above slot is entered. The status method will contain in outline: void SubViewShell::PrintState( SfxItemSet &rState ) { if ( rState.GetItemState( SID_PRINTDOCDIRECT ) != SFX_ITEM_UNKNOWN ) GetSlotState( SID_PRINTDOCDIRECT, SfxViewShell::GetInterface(), &rState ); ... } [Cross-reference] */ { // Get Slot on the given Interface if ( !pIF ) pIF = GetInterface(); SfxItemState eState; SfxItemPool &rPool = GetPool(); const SfxSlot* pSlot = NULL; if ( nSlotId >= SID_VERB_START && nSlotId <= SID_VERB_END ) pSlot = GetVerbSlot_Impl(nSlotId); if ( !pSlot ) pSlot = pIF->GetSlot(nSlotId); if ( pSlot ) // Map on Which-Id if possible nSlotId = pSlot->GetWhich( rPool ); // Get Item and Item status const SfxPoolItem *pItem = NULL; SfxItemSet aSet( rPool, nSlotId, nSlotId ); // else pItem dies too soon if ( pSlot ) { // Call Status method SfxStateFunc pFunc = pSlot->GetStateFnc(); if ( pFunc ) CallState( pFunc, aSet ); eState = aSet.GetItemState( nSlotId, sal_True, &pItem ); // get default Item if possible if ( eState == SFX_ITEM_DEFAULT ) { if ( SfxItemPool::IsWhich(nSlotId) ) pItem = &rPool.GetDefaultItem(nSlotId); else eState = SFX_ITEM_DONTCARE; } } else eState = SFX_ITEM_UNKNOWN; // Evaluate Item and item status and possibly maintain them in pStateSet SfxPoolItem *pRetItem = 0; if ( eState <= SFX_ITEM_DISABLED ) { if ( pStateSet ) pStateSet->DisableItem(nSlotId); return 0; } else if ( eState == SFX_ITEM_DONTCARE ) { if ( pStateSet ) pStateSet->ClearItem(nSlotId); pRetItem = new SfxVoidItem(0); } else { if ( pStateSet && pStateSet->Put( *pItem ) ) return &pStateSet->Get( pItem->Which() ); pRetItem = pItem->Clone(); } DeleteItemOnIdle(pRetItem); return pRetItem; } //-------------------------------------------------------------------- SFX_EXEC_STUB(SfxShell, VerbExec) SFX_STATE_STUB(SfxShell, VerbState) void SfxShell::SetVerbs(const com::sun::star::uno::Sequence < com::sun::star::embed::VerbDescriptor >& aVerbs) { SfxViewShell *pViewSh = PTR_CAST ( SfxViewShell, this); DBG_ASSERT(pViewSh, "Only call SetVerbs at the ViewShell!"); if ( !pViewSh ) return; // First make all Statecaches dirty, so that no-one no longer tries to use // the Slots { SfxBindings *pBindings = pViewSh->GetViewFrame()->GetDispatcher()->GetBindings(); sal_uInt16 nCount = pImp->aSlotArr.Count(); for (sal_uInt16 n1=0; n1Invalidate(nId, sal_False, sal_True); } } sal_uInt16 nr=0; for (sal_Int32 n=0; n SID_VERB_END) break; SfxSlot *pNewSlot = new SfxSlot; pNewSlot->nSlotId = nSlotId; pNewSlot->nGroupId = 0; // Verb slots must be executed asynchronously, so that they can be // destroyed while executing. pNewSlot->nFlags = SFX_SLOT_ASYNCHRON | SFX_SLOT_CONTAINER; pNewSlot->nMasterSlotId = 0; pNewSlot->nValue = 0; pNewSlot->fnExec = SFX_STUB_PTR(SfxShell,VerbExec); pNewSlot->fnState = SFX_STUB_PTR(SfxShell,VerbState); pNewSlot->pType = 0; HACK(SFX_TYPE(SfxVoidItem)) pNewSlot->pName = U2S(aVerbs[n].VerbName).getStr(); pNewSlot->pLinkedSlot = 0; pNewSlot->nArgDefCount = 0; pNewSlot->pFirstArgDef = 0; pNewSlot->pUnoName = 0; if (pImp->aSlotArr.Count()) { SfxSlot *pSlot = (pImp->aSlotArr)[0]; pNewSlot->pNextSlot = pSlot->pNextSlot; pSlot->pNextSlot = pNewSlot; } else pNewSlot->pNextSlot = pNewSlot; pImp->aSlotArr.Insert(pNewSlot, (sal_uInt16) n); } pImp->aVerbList = aVerbs; if (pViewSh) { // The status of SID_OBJECT is collected in the controller directly on // the Shell, it is thus enough to encourage a new status update SfxBindings *pBindings = pViewSh->GetViewFrame()->GetDispatcher()-> GetBindings(); pBindings->Invalidate( SID_OBJECT, sal_True, sal_True ); } } //-------------------------------------------------------------------- const com::sun::star::uno::Sequence < com::sun::star::embed::VerbDescriptor >& SfxShell::GetVerbs() const { return pImp->aVerbList; } //-------------------------------------------------------------------- void SfxShell::VerbExec(SfxRequest& rReq) { sal_uInt16 nId = rReq.GetSlot(); SfxViewShell *pViewShell = GetViewShell(); if ( pViewShell ) { sal_Bool bReadOnly = pViewShell->GetObjectShell()->IsReadOnly(); com::sun::star::uno::Sequence < com::sun::star::embed::VerbDescriptor > aList = pViewShell->GetVerbs(); for (sal_Int32 n=0, nVerb=0; nDoVerb(aList[n].VerbID); rReq.Done(); return; } } } } //-------------------------------------------------------------------- void SfxShell::VerbState(SfxItemSet& ) { } //-------------------------------------------------------------------- const SfxSlot* SfxShell::GetVerbSlot_Impl(sal_uInt16 nId) const { com::sun::star::uno::Sequence < com::sun::star::embed::VerbDescriptor > rList = pImp->aVerbList; DBG_ASSERT(nId >= SID_VERB_START && nId <= SID_VERB_END,"Wrong VerbId!"); sal_uInt16 nIndex = nId - SID_VERB_START; DBG_ASSERT(nIndex < rList.getLength(),"Wrong VerbId!"); if (nIndex < rList.getLength()) return pImp->aSlotArr[nIndex]; else return 0; } //-------------------------------------------------------------------- void SfxShell::SetHelpId(sal_uIntPtr nId) { pImp->nHelpId = nId; } //-------------------------------------------------------------------- sal_uIntPtr SfxShell::GetHelpId() const { return pImp->nHelpId; } //-------------------------------------------------------------------- SfxObjectShell* SfxShell::GetObjectShell() { if ( GetViewShell() ) return GetViewShell()->GetViewFrame()->GetObjectShell(); else return NULL; } //-------------------------------------------------------------------- sal_Bool SfxShell::HasUIFeature( sal_uInt32 ) { return sal_False; } long DispatcherUpdate_Impl( void*, void* pArg ) { ((SfxDispatcher*) pArg)->Update_Impl( sal_True ); ((SfxDispatcher*) pArg)->GetBindings()->InvalidateAll(sal_False); return 0; } void SfxShell::UIFeatureChanged() { SfxViewFrame *pFrame = GetFrame(); if ( pFrame && pFrame->IsVisible() ) { // Also force an update, if dispatcher is already updated otherwise // something my get stuck in the bunkered tools. Asynchronous call to // prevent recursion. if ( !pImp->pUpdater ) pImp->pUpdater = new svtools::AsynchronLink( Link( this, DispatcherUpdate_Impl ) ); // Multiple views allowed pImp->pUpdater->Call( pFrame->GetDispatcher(), sal_True ); } } void SfxShell::SetDisableFlags( sal_uIntPtr nFlags ) { pImp->nDisableFlags = nFlags; } sal_uIntPtr SfxShell::GetDisableFlags() const { return pImp->nDisableFlags; } SfxItemSet* SfxShell::CreateItemSet( sal_uInt16 ) { return NULL; } void SfxShell::ApplyItemSet( sal_uInt16, const SfxItemSet& ) { } void SfxShell::SetViewShell_Impl( SfxViewShell* pView ) { pImp->pViewSh = pView; } /* vim:set shiftwidth=4 softtabstop=4 expandtab: */