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 .
20 #include <com/sun/star/embed/VerbDescriptor.hpp>
21 #include <com/sun/star/embed/VerbAttributes.hpp>
22 #include <basic/sbstar.hxx>
23 #include <officecfg/Office/Common.hxx>
24 #include <rtl/ustring.hxx>
25 #include <sal/log.hxx>
26 #include <svl/itempool.hxx>
27 #include <svl/undo.hxx>
28 #include <svtools/itemdel.hxx>
29 #include <svtools/asynclink.hxx>
30 #include <basic/sbx.hxx>
32 #include <sfx2/app.hxx>
33 #include <sfx2/shell.hxx>
34 #include <sfx2/bindings.hxx>
35 #include <sfx2/dispatch.hxx>
36 #include <sfx2/viewfrm.hxx>
37 #include <sfx2/objface.hxx>
38 #include <sfx2/objsh.hxx>
39 #include <sfx2/viewsh.hxx>
40 #include "sfxtypes.hxx"
41 #include <sfx2/request.hxx>
42 #include <sfx2/mnumgr.hxx>
43 #include "statcach.hxx"
44 #include <sfx2/msgpool.hxx>
45 #include <sfx2/sidebar/ContextChangeBroadcaster.hxx>
47 //====================================================================
51 //====================================================================
55 //====================================================================
56 class SfxVerbSlotArr_Impl
: public std::vector
<SfxSlot
*>
59 ~SfxVerbSlotArr_Impl()
61 for(const_iterator it
= begin(); it
!= end(); ++it
)
66 using namespace com::sun::star
;
68 //=========================================================================
70 //=========================================================================
71 struct SfxShell_Impl
: public SfxBroadcaster
73 String aObjectName
; // Name of Sbx-Objects
74 SfxItemPtrMap aItems
; // Data exchange on Item level
75 SfxViewShell
* pViewSh
; // SfxViewShell if Shell is
76 // ViewFrame/ViewShell/SubShell list
77 SfxViewFrame
* pFrame
; // Frame, if <UI-active>
78 SfxRepeatTarget
* pRepeatTarget
; // SbxObjectRef xParent;
81 sal_uIntPtr nDisableFlags
;
83 svtools::AsynchronLink
* pExecuter
;
84 svtools::AsynchronLink
* pUpdater
;
85 SfxVerbSlotArr_Impl aSlotArr
;
87 com::sun::star::uno::Sequence
< com::sun::star::embed::VerbDescriptor
> aVerbList
;
88 ::sfx2::sidebar::ContextChangeBroadcaster maContextChangeBroadcaster
;
90 SfxShell_Impl() : pExecuter( 0 ), pUpdater( 0 ) {}
91 ~SfxShell_Impl() { delete pExecuter
; delete pUpdater
;}
94 //=========================================================================
96 //=========================================================================
98 void SfxShell::EmptyExecStub(SfxShell
*, SfxRequest
&)
102 void SfxShell::EmptyStateStub(SfxShell
*, SfxItemSet
&)
110 The constructor of the SfxShell class initializes only simple types,
111 the corresponding SbxObject is only created on-demand. Therefore,
112 the application of a SfxShell instance is very cheap.
119 DBG_CTOR(SfxShell
, 0);
120 pImp
= new SfxShell_Impl
;
123 pImp
->pRepeatTarget
= 0;
124 pImp
->bInAppBASIC
= sal_False
;
126 pImp
->bActive
= sal_False
;
127 pImp
->nDisableFlags
= 0;
130 //-------------------------------------------------------------------------
132 SfxShell::SfxShell( SfxViewShell
*pViewSh
)
136 The constructor of the SfxShell class initializes only simple types,
137 the corresponding SbxObject is only created on-demand. Therefore,
138 the application of a SfxShell instance is very cheap.
145 DBG_CTOR(SfxShell
, 0);
146 pImp
= new SfxShell_Impl
;
147 pImp
->pViewSh
= pViewSh
;
149 pImp
->pRepeatTarget
= 0;
150 pImp
->bInAppBASIC
= sal_False
;
152 pImp
->bActive
= sal_False
;
155 //--------------------------------------------------------------------
157 SfxShell::~SfxShell()
161 The connection to a possible corresponding SbxObject is dissolved.
162 The SbxObject may continoue to exist, but can not any longer perform
163 any functions and can not provide any properties.
167 DBG_DTOR(SfxShell
, 0);
173 //--------------------------------------------------------------------
175 void SfxShell::SetName( const String
&rName
)
179 Sets the name of the Shell object. With this name, the SfxShell instance
180 of BASIC can be expressed.
184 pImp
->aObjectName
= rName
;
187 //--------------------------------------------------------------------
189 const String
& SfxShell::GetName() const
193 Returns the name of the Shell object. With this name, the SfxShell instance
194 of BASIC can be expressed.
198 return pImp
->aObjectName
;
201 //--------------------------------------------------------------------
203 SfxDispatcher
* SfxShell::GetDispatcher() const
207 This method returns a pointer to the <SfxDispatcher>, when the SfxShell
208 is currently <UI-active> or a NULL-pointer if it is not UI-active.
210 The returned pointer is only valid in the immediate context of the method
215 return pImp
->pFrame
? pImp
->pFrame
->GetDispatcher() : 0;
218 //--------------------------------------------------------------------
220 SfxViewShell
* SfxShell::GetViewShell() const
224 Returns the SfxViewShell in which they are located in the subshells.
225 Otherwise, and if not specified by the App developer, this method
230 return pImp
->pViewSh
;
233 //--------------------------------------------------------------------
235 SfxViewFrame
* SfxShell::GetFrame() const
239 This method returns a pointer to the <SfxViewFrame> to which this SfxShell
240 instance is associated or in which they currently is <UI-active>.
241 A NULL pointer is returned if this SfxShell instance is not UI-active at
242 the moment and also no SfxViewFrame is permanently assigned.
244 The returned pointer is only valid in the immediate context of the method
249 Only instances of a subclass of SfxApplication and SfxObjectShell
250 should here provide a NULL-pointer. Otherwise, there is an error in the
251 application program (wrong constructor was called from SfxShell).
255 <SfxViewShell::GetViewFrame()const>
262 return pImp
->pViewSh
->GetViewFrame();
266 //--------------------------------------------------------------------
268 const SfxPoolItem
* SfxShell::GetItem
270 sal_uInt16 nSlotId
// Slot-Id of the querying <SfxPoolItem>s
275 With this method any objects of <SfxPoolItemu> subclasses can be accessed.
276 This exchange method is needed if, for example special <SfxToolBoxControl>
277 subclasses need access to certain data such as the <SfxObjectShell>.
279 The returned instance belongs to the particular SfxShell and may be
280 used only in the immediate context of the method call.
284 <SfxShell::PutItem(const SfxPoolItem&)>
285 <SfxShell::RemoveItem(sal_uInt16)>
289 SfxItemPtrMap::iterator it
= pImp
->aItems
.find( nSlotId
);
290 if( it
!= pImp
->aItems
.end() )
295 //--------------------------------------------------------------------
297 void SfxShell::PutItem
299 const SfxPoolItem
& rItem
/* Instance, of which a copy is created,
300 which is stored in the SfxShell in a list. */
305 With this method, any objects of subclasses of <SfxPoolItem> can be made
306 available. This exchange technology is needed if, for example, special
307 <SfxToolBoxControl> Subclasses need access to certain data such as the
310 If a SfxPoolItem exists with the same slot ID, it is deleted automatically.
314 <SfxShell::RemoveItem(sal_uInt16)>
315 <SfxShell::GetItem(sal_uInt16)>
319 DBG_ASSERT( !rItem
.ISA(SfxSetItem
), "SetItems aren't allowed here" );
320 DBG_ASSERT( SfxItemPool::IsSlot( rItem
.Which() ),
321 "items with Which-Ids aren't allowed here" );
323 // MSC made a mess here of WNT/W95, beware of changes
324 SfxPoolItem
*pItem
= rItem
.Clone();
325 SfxPoolItemHint
aItemHint( pItem
);
326 const sal_uInt16 nWhich
= rItem
.Which();
328 SfxItemPtrMap::iterator it
= pImp
->aItems
.find( nWhich
);
329 if( it
!= pImp
->aItems
.end() )
331 SfxPoolItem
*pLoopItem
= it
->second
;
336 // if active, notify Bindings
337 SfxDispatcher
*pDispat
= GetDispatcher();
340 SfxBindings
* pBindings
= pDispat
->GetBindings();
341 pBindings
->Broadcast( aItemHint
);
342 sal_uInt16 nSlotId
= nWhich
; //pItem->GetSlotId();
343 SfxStateCache
* pCache
= pBindings
->GetStateCache( nSlotId
);
346 pCache
->SetState( SFX_ITEM_AVAILABLE
, pItem
->Clone(), sal_True
);
347 pCache
->SetCachedState( sal_True
);
354 Broadcast( aItemHint
);
355 pImp
->aItems
[ pItem
->Which() ] = pItem
;
359 //--------------------------------------------------------------------
361 SfxInterface
* SfxShell::GetInterface() const
365 With this virtual method, which is automatically overloaded by each subclass
366 with its own slots through the macro <SFX_DECL_INTERFACE>, one can access
367 each of the <SfxInterface> instance beloning to the subclass.
369 The class SfxShell itself has no own SfxInterface (no slots), therefore a
370 NULL-pointer is returned.
374 return GetStaticInterface();
377 //--------------------------------------------------------------------
379 ::svl::IUndoManager
* SfxShell::GetUndoManager()
383 Each Subclass of SfxShell can hava a <SfxUndoManager>. This can be set in
384 the derived class with <SfxShell:SetUndoManager()>.
386 The class SfxShell itself does not have a SfxUndoManager, a NULL-pointer
387 is therefore returned.
394 //--------------------------------------------------------------------
396 void SfxShell::SetUndoManager( ::svl::IUndoManager
*pNewUndoMgr
)
400 Sets a <SfxUndoManager> for this <SfxShell> Instance. For the undo
401 is only the undo-manager used for SfxShell at the top of the stack of each
404 On the given <SfxUndoManager> is automatically the current
405 Max-Undo-Action-Count setting set form the options.
407 'pNewUndoMgr' must exist until the Destuctor of SfxShell instance is called
408 or until the next 'SetUndoManager()'.
412 OSL_ENSURE( ( pUndoMgr
== NULL
) || ( pNewUndoMgr
== NULL
) || ( pUndoMgr
== pNewUndoMgr
),
413 "SfxShell::SetUndoManager: exchanging one non-NULL manager with another non-NULL manager? Suspicious!" );
414 // there's at least one client of our UndoManager - the DocumentUndoManager at the SfxBaseModel - which
415 // caches the UndoManager, and registers itself as listener. If exchanging non-NULL UndoManagers is really
416 // a supported scenario (/me thinks it is not), then we would need to notify all such clients instances.
418 pUndoMgr
= pNewUndoMgr
;
420 pUndoMgr
->SetMaxUndoActionCount(
421 officecfg::Office::Common::Undo::Steps::get());
424 //--------------------------------------------------------------------
426 SfxRepeatTarget
* SfxShell::GetRepeatTarget() const
430 Returns a pointer to the <SfxRepeatTarget> instance that is used in
431 SID_REPEAT as repeat target when it is addressed from the <SfxUndoManager>
432 supplied by this SfxShell. The return value can be NULL.
436 A derivation of <SfxShell> or one of its subclasses of <SfxRepeatTarget>
437 is not recommended, as compiler errors are provoked.
438 (due to Call-to-Pointer-to-Member-Function to the subclass).
442 return pImp
->pRepeatTarget
;
445 //--------------------------------------------------------------------
447 void SfxShell::SetRepeatTarget( SfxRepeatTarget
*pTarget
)
451 Sets the <SfxRepeatTarget> instance that is used in SID_REPEAT as
452 RepeatTarget, when the current supplied by this <SfxUndoManager> is
453 addressed. By 'pTarget==0' the SID_REPEAT is disabled for this SfxShell.
454 The instance '*pTarget' must live as long as it is registered.
458 A derivation of <SfxShell> or one of its subclasses of <SfxRepeatTarget>
459 is not recommended, as compiler errors are provoked.
460 (due to Call-to-Pointer-to-Member-Function to the subclass).
464 pImp
->pRepeatTarget
= pTarget
;
467 //--------------------------------------------------------------------
469 void SfxShell::Invalidate
471 sal_uInt16 nId
/* Invalidated Slot-Id or Which-Id.
472 If these are 0 (default), then all
473 by this Shell currently handled Slot-Ids are
479 With this method can the slots of the subclasses be invalidated through the
480 slot Id or alternatively through the Which ID. Slot IDs, which are
481 inherited by the subclass are also invalidert.
485 <SfxBindings::Invalidate(sal_uInt16)>
486 <SfxBindings::InvalidateAll(sal_Bool)>
490 if ( !GetViewShell() )
492 OSL_FAIL( "wrong Invalidate method called!" );
496 Invalidate_Impl( GetViewShell()->GetViewFrame()->GetBindings(), nId
);
499 void SfxShell::Invalidate_Impl( SfxBindings
& rBindings
, sal_uInt16 nId
)
503 rBindings
.InvalidateShell( *this, sal_False
);
507 const SfxInterface
*pIF
= GetInterface();
510 const SfxSlot
*pSlot
= pIF
->GetSlot(nId
);
513 // At Enum-Slots invalidate the Master-Slot
514 if ( SFX_KIND_ENUM
== pSlot
->GetKind() )
515 pSlot
= pSlot
->GetLinkedSlot();
517 // Invalidate the Slot itself and possible also all Slave-Slots
518 rBindings
.Invalidate( pSlot
->GetSlotId() );
519 for ( const SfxSlot
*pSlave
= pSlot
->GetLinkedSlot();
520 pSlave
&& pIF
->ContainsSlot_Impl( pSlave
) &&
521 pSlave
->GetLinkedSlot() == pSlot
;
523 rBindings
.Invalidate( pSlave
->GetSlotId() );
528 pIF
= pIF
->GetGenoType();
533 DBG_WARNING( "W3: invalidating slot-id unknown in shell" );
537 //--------------------------------------------------------------------
539 void SfxShell::DoActivate_Impl( SfxViewFrame
*pFrame
, sal_Bool bMDI
)
543 This method controls the activation of SfxShell instance. First, by calling
544 the virtual method <SfxShell::Activate(sal_Bool)> which gives the subclass the
545 opportunity to respond to the event.
547 When bMDI == TRUE, the associated SbxObject is being 'armed', so that
548 unqualified methods of the object (without the name of the object)
549 from BASIC are found.
554 const SfxInterface
*p_IF
= GetInterface();
560 "SfxShell::DoActivate() " << this << " " << GetInterface()->GetName()
561 << " bMDI " << (bMDI
? "MDI" : ""));
565 // Remember Frame, in which it was activated
566 pImp
->pFrame
= pFrame
;
567 pImp
->bActive
= sal_True
;
574 //--------------------------------------------------------------------
576 void SfxShell::DoDeactivate_Impl( SfxViewFrame
*pFrame
, sal_Bool bMDI
)
580 This method controls the deactivation of the SfxShell instance. When
581 bMDI == TRUE the SbxObject is first set to a status that only qualified
582 BASIC methods can be called.
584 Then the subclass gets the opportunity in every case to respond to the
585 event by calling the virtual method <SfxShell::Deactivate(sal_Bool)>.
590 const SfxInterface
*p_IF
= GetInterface();
596 "SfxShell::DoDeactivate()" << this << " " << GetInterface()->GetName()
597 << " bMDI " << (bMDI
? "MDI" : ""));
599 // Only when it comes from a Frame
600 // (not when for instance by poping BASIC-IDE from AppDisp)
601 if ( bMDI
&& pImp
->pFrame
== pFrame
)
605 pImp
->bActive
= sal_False
;
612 //--------------------------------------------------------------------
614 sal_Bool
SfxShell::IsActive() const
616 return pImp
->bActive
;
619 //--------------------------------------------------------------------
621 void SfxShell::Activate
623 sal_Bool
/*bMDI*/ /* TRUE
624 the <SfxDispatcher>, on which the SfxShell is
625 located, is activated or the SfxShell instance
626 was pushed on an active SfxDispatcher.
627 (compare with SystemWindow::IsMDIActivate())
630 the <SfxViewFrame>, on which SfxDispatcher
631 the SfxShell instance is located, was
632 activated. (for example by a closing dialoge) */
637 Virtual method that is called when enabling the SfxShell instance,
638 in order to give the Subclasses the opportunity to respond to the
643 StarView SystemWindow::Activate(sal_Bool)
647 BroadcastContextForActivation(true);
650 //--------------------------------------------------------------------
652 void SfxShell::Deactivate
654 sal_Bool
/*bMDI*/ /* TRUE
655 the <SfxDispatcher>, on which the SfxShell is
656 located, is inactivated or the SfxShell instance
657 was popped on an active SfxDispatcher.
658 (compare with SystemWindow::IsMDIActivate())
661 the <SfxViewFrame>, on which SfxDispatcher
662 the SfxShell instance is located, was
663 deactivated. (for example by a dialoge) */
669 Virtual method that is called when disabling the SfxShell instance,
670 to give the Subclasses the opportunity to respond to the disabling.
674 StarView SystemWindow::Dectivate(sal_Bool)
678 BroadcastContextForActivation(false);
682 void SfxShell::ParentActivate
688 A parent of the <SfxDispatcher> on which the SfxShell is located, has
689 become active, or the SfxShell instance was pushed on a <SfxDispatcher>,
690 which parent is active.
692 The base implementation is empty and does not need to be called.
701 //--------------------------------------------------------------------
703 void SfxShell::ParentDeactivate
709 The active parent of the <SfxDispatcher> on which the SfxShell is located,
712 The base implementation is empty and does not need to be called.
716 SfxShell::Deactivate()
721 //--------------------------------------------------------------------
723 ResMgr
* SfxShell::GetResMgr() const
727 This method provides the ResMgr of the <Resource-DLL> that are used by
728 the SfxShell instance. If this is a NULL-pointer, then the current
729 resource manager is to be used.
733 return GetInterface()->GetResMgr();
736 //--------------------------------------------------------------------
738 bool SfxShell::CanExecuteSlot_Impl( const SfxSlot
&rSlot
)
742 This method determines by calling the status function whether 'rSlot'
743 can be executed currently.
747 SfxItemPool
&rPool
= GetPool();
748 const sal_uInt16 nId
= rSlot
.GetWhich( rPool
);
749 SfxItemSet
aSet(rPool
, nId
, nId
);
750 SfxStateFunc pFunc
= rSlot
.GetStateFnc();
751 CallState( pFunc
, aSet
);
752 return aSet
.GetItemState(nId
) != SFX_ITEM_DISABLED
;
755 //--------------------------------------------------------------------
757 long ShellCall_Impl( void* pObj
, void* pArg
)
759 ((SfxShell
* )pObj
)->ExecuteSlot( *(SfxRequest
*)pArg
, (SfxInterface
*)0L );
765 Asynchronous ExecuteSlot for the RELOAD
768 //--------------------------------------------------------------------
769 const SfxPoolItem
* SfxShell::ExecuteSlot( SfxRequest
& rReq
, sal_Bool bAsync
)
772 return ExecuteSlot( rReq
, (SfxInterface
*)0L );
775 if( !pImp
->pExecuter
)
776 pImp
->pExecuter
= new svtools::AsynchronLink(
777 Link( this, ShellCall_Impl
) );
778 pImp
->pExecuter
->Call( new SfxRequest( rReq
) );
783 const SfxPoolItem
* SfxShell::ExecuteSlot
785 SfxRequest
&rReq
, // the relayed <SfxRequest>
786 const SfxInterface
* pIF
// default = 0 means get virtually
791 This method allows you to forward a <SfxRequest> to the specified
796 In a derived class of SfxViewShell the SID_PRINTDOCDIRECT will be
797 intercepted. Under certain circumstances a query should appear before
798 you print, and the request will be aborted if necessary.
800 Also in the IDL of this subclass of the above slot is entered. The status
801 method will contain in outline:
803 void SubViewShell::Exec( SfxRequest &rReq )
805 if ( rReq.GetSlot() == SID_PRINTDOCDIRECT )
809 ExecuteSlot( rReq, SfxViewShell::GetInterface() );
813 It usually takes no rReq.Done() to be called as that is already completed
814 in implementation of the SfxViewShell, for instance it has been canceled.
818 <SfxShell::GetSlotState(sal_uInt16,const SfxInterface*,SfxItemSet*)>
823 pIF
= GetInterface();
825 sal_uInt16 nSlot
= rReq
.GetSlot();
826 const SfxSlot
* pSlot
= NULL
;
827 if ( nSlot
>= SID_VERB_START
&& nSlot
<= SID_VERB_END
)
828 pSlot
= GetVerbSlot_Impl(nSlot
);
830 pSlot
= pIF
->GetSlot(nSlot
);
831 DBG_ASSERT( pSlot
, "slot not supported" );
833 SfxExecFunc pFunc
= pSlot
->GetExecFnc();
835 CallExec( pFunc
, rReq
);
837 return rReq
.GetReturnValue();
840 //--------------------------------------------------------------------
842 const SfxPoolItem
* SfxShell::GetSlotState
844 sal_uInt16 nSlotId
, // Slot-Id to the Slots in question
845 const SfxInterface
* pIF
, // default = 0 means get virtually
846 SfxItemSet
* pStateSet
// SfxItemSet of the Slot-State method
851 This method returns the status of the slot with the specified slot ID
852 on the specified interface.
854 If the slot is disabled or in this SfxShell (and their parent shells) are
855 not known, a Null-pointer is returned.
857 If the slot does not have a Status, a SfxVoidItem is returned.
859 The status is set directly in this Set when pStateSet != 0 , so that
860 overloaded Slots of the <SfxShell> Subclasses and also in the Status
861 method of the base implementation can be called.
865 In a derived class of SfxViewShell the SID_PRINTDOCDIRECT will be
866 intercepted. Under certain circumstances a query should appear before
867 you print, and the request will be aborted if necessary.
869 Also in the IDL of this subclass of the above slot is entered. The status
870 method will contain in outline:
872 void SubViewShell::PrintState( SfxItemSet &rState )
874 if ( rState.GetItemState( SID_PRINTDOCDIRECT ) != SFX_ITEM_UNKNOWN )
875 GetSlotState( SID_PRINTDOCDIRECT, SfxViewShell::GetInterface(),
882 <SfxShell::ExecuteSlot(SfxRequest&)>
886 // Get Slot on the given Interface
888 pIF
= GetInterface();
890 SfxItemPool
&rPool
= GetPool();
892 const SfxSlot
* pSlot
= NULL
;
893 if ( nSlotId
>= SID_VERB_START
&& nSlotId
<= SID_VERB_END
)
894 pSlot
= GetVerbSlot_Impl(nSlotId
);
896 pSlot
= pIF
->GetSlot(nSlotId
);
898 // Map on Which-Id if possible
899 nSlotId
= pSlot
->GetWhich( rPool
);
901 // Get Item and Item status
902 const SfxPoolItem
*pItem
= NULL
;
903 SfxItemSet
aSet( rPool
, nSlotId
, nSlotId
); // else pItem dies too soon
906 // Call Status method
907 SfxStateFunc pFunc
= pSlot
->GetStateFnc();
909 CallState( pFunc
, aSet
);
910 eState
= aSet
.GetItemState( nSlotId
, sal_True
, &pItem
);
912 // get default Item if possible
913 if ( eState
== SFX_ITEM_DEFAULT
)
915 if ( SfxItemPool::IsWhich(nSlotId
) )
916 pItem
= &rPool
.GetDefaultItem(nSlotId
);
918 eState
= SFX_ITEM_DONTCARE
;
922 eState
= SFX_ITEM_UNKNOWN
;
924 // Evaluate Item and item status and possibly maintain them in pStateSet
925 SfxPoolItem
*pRetItem
= 0;
926 if ( eState
<= SFX_ITEM_DISABLED
)
929 pStateSet
->DisableItem(nSlotId
);
932 else if ( eState
== SFX_ITEM_DONTCARE
)
935 pStateSet
->ClearItem(nSlotId
);
936 pRetItem
= new SfxVoidItem(0);
940 if ( pStateSet
&& pStateSet
->Put( *pItem
) )
941 return &pStateSet
->Get( pItem
->Which() );
942 pRetItem
= pItem
->Clone();
944 DeleteItemOnIdle(pRetItem
);
949 //--------------------------------------------------------------------
951 SFX_EXEC_STUB(SfxShell
, VerbExec
)
952 SFX_STATE_STUB(SfxShell
, VerbState
)
954 void SfxShell::SetVerbs(const com::sun::star::uno::Sequence
< com::sun::star::embed::VerbDescriptor
>& aVerbs
)
956 SfxViewShell
*pViewSh
= PTR_CAST ( SfxViewShell
, this);
958 DBG_ASSERT(pViewSh
, "Only call SetVerbs at the ViewShell!");
962 // First make all Statecaches dirty, so that no-one no longer tries to use
965 SfxBindings
*pBindings
=
966 pViewSh
->GetViewFrame()->GetDispatcher()->GetBindings();
967 sal_uInt16 nCount
= pImp
->aSlotArr
.size();
968 for (sal_uInt16 n1
=0; n1
<nCount
; n1
++)
970 sal_uInt16 nId
= SID_VERB_START
+ n1
;
971 pBindings
->Invalidate(nId
, sal_False
, sal_True
);
976 for (sal_Int32 n
=0; n
<aVerbs
.getLength(); n
++)
978 sal_uInt16 nSlotId
= SID_VERB_START
+ nr
++;
979 DBG_ASSERT(nSlotId
<= SID_VERB_END
, "To many Verbs!");
980 if (nSlotId
> SID_VERB_END
)
983 SfxSlot
*pNewSlot
= new SfxSlot
;
984 pNewSlot
->nSlotId
= nSlotId
;
985 pNewSlot
->nGroupId
= 0;
987 // Verb slots must be executed asynchronously, so that they can be
988 // destroyed while executing.
989 pNewSlot
->nFlags
= SFX_SLOT_ASYNCHRON
| SFX_SLOT_CONTAINER
;
990 pNewSlot
->nMasterSlotId
= 0;
991 pNewSlot
->nValue
= 0;
992 pNewSlot
->fnExec
= SFX_STUB_PTR(SfxShell
,VerbExec
);
993 pNewSlot
->fnState
= SFX_STUB_PTR(SfxShell
,VerbState
);
994 pNewSlot
->pType
= 0; // HACK(SFX_TYPE(SfxVoidItem)) ???
995 pNewSlot
->pName
= U2S(aVerbs
[n
].VerbName
).getStr();
996 pNewSlot
->pLinkedSlot
= 0;
997 pNewSlot
->nArgDefCount
= 0;
998 pNewSlot
->pFirstArgDef
= 0;
999 pNewSlot
->pUnoName
= 0;
1001 if (!pImp
->aSlotArr
.empty())
1003 SfxSlot
*pSlot
= pImp
->aSlotArr
[0];
1004 pNewSlot
->pNextSlot
= pSlot
->pNextSlot
;
1005 pSlot
->pNextSlot
= pNewSlot
;
1008 pNewSlot
->pNextSlot
= pNewSlot
;
1010 pImp
->aSlotArr
.insert(pImp
->aSlotArr
.begin() + (sal_uInt16
) n
, pNewSlot
);
1013 pImp
->aVerbList
= aVerbs
;
1017 // The status of SID_OBJECT is collected in the controller directly on
1018 // the Shell, it is thus enough to encourage a new status update
1019 SfxBindings
*pBindings
= pViewSh
->GetViewFrame()->GetDispatcher()->
1021 pBindings
->Invalidate( SID_OBJECT
, sal_True
, sal_True
);
1025 //--------------------------------------------------------------------
1027 const com::sun::star::uno::Sequence
< com::sun::star::embed::VerbDescriptor
>& SfxShell::GetVerbs() const
1029 return pImp
->aVerbList
;
1032 //--------------------------------------------------------------------
1034 void SfxShell::VerbExec(SfxRequest
& rReq
)
1036 sal_uInt16 nId
= rReq
.GetSlot();
1037 SfxViewShell
*pViewShell
= GetViewShell();
1040 sal_Bool bReadOnly
= pViewShell
->GetObjectShell()->IsReadOnly();
1041 com::sun::star::uno::Sequence
< com::sun::star::embed::VerbDescriptor
> aList
= pViewShell
->GetVerbs();
1042 for (sal_Int32 n
=0, nVerb
=0; n
<aList
.getLength(); n
++)
1044 // check for ReadOnly verbs
1045 if ( bReadOnly
&& !(aList
[n
].VerbAttributes
& embed::VerbAttributes::MS_VERBATTR_NEVERDIRTIES
) )
1048 // check for verbs that shouldn't appear in the menu
1049 if ( !(aList
[n
].VerbAttributes
& embed::VerbAttributes::MS_VERBATTR_ONCONTAINERMENU
) )
1052 if (nId
== SID_VERB_START
+ nVerb
++)
1054 pViewShell
->DoVerb(aList
[n
].VerbID
);
1062 //--------------------------------------------------------------------
1064 void SfxShell::VerbState(SfxItemSet
& )
1068 //--------------------------------------------------------------------
1070 const SfxSlot
* SfxShell::GetVerbSlot_Impl(sal_uInt16 nId
) const
1072 com::sun::star::uno::Sequence
< com::sun::star::embed::VerbDescriptor
> rList
= pImp
->aVerbList
;
1074 DBG_ASSERT(nId
>= SID_VERB_START
&& nId
<= SID_VERB_END
,"Wrong VerbId!");
1075 sal_uInt16 nIndex
= nId
- SID_VERB_START
;
1076 DBG_ASSERT(nIndex
< rList
.getLength(),"Wrong VerbId!");
1078 if (nIndex
< rList
.getLength())
1079 return pImp
->aSlotArr
[nIndex
];
1084 //--------------------------------------------------------------------
1086 void SfxShell::SetHelpId(sal_uIntPtr nId
)
1088 pImp
->nHelpId
= nId
;
1091 //--------------------------------------------------------------------
1093 sal_uIntPtr
SfxShell::GetHelpId() const
1095 return pImp
->nHelpId
;
1098 //--------------------------------------------------------------------
1100 SfxObjectShell
* SfxShell::GetObjectShell()
1102 if ( GetViewShell() )
1103 return GetViewShell()->GetViewFrame()->GetObjectShell();
1108 //--------------------------------------------------------------------
1110 sal_Bool
SfxShell::HasUIFeature( sal_uInt32
)
1115 long DispatcherUpdate_Impl( void*, void* pArg
)
1117 ((SfxDispatcher
*) pArg
)->Update_Impl( sal_True
);
1118 ((SfxDispatcher
*) pArg
)->GetBindings()->InvalidateAll(sal_False
);
1122 void SfxShell::UIFeatureChanged()
1124 SfxViewFrame
*pFrame
= GetFrame();
1125 if ( pFrame
&& pFrame
->IsVisible() )
1127 // Also force an update, if dispatcher is already updated otherwise
1128 // something my get stuck in the bunkered tools. Asynchronous call to
1129 // prevent recursion.
1130 if ( !pImp
->pUpdater
)
1131 pImp
->pUpdater
= new svtools::AsynchronLink( Link( this, DispatcherUpdate_Impl
) );
1133 // Multiple views allowed
1134 pImp
->pUpdater
->Call( pFrame
->GetDispatcher(), sal_True
);
1138 void SfxShell::SetDisableFlags( sal_uIntPtr nFlags
)
1140 pImp
->nDisableFlags
= nFlags
;
1143 sal_uIntPtr
SfxShell::GetDisableFlags() const
1145 return pImp
->nDisableFlags
;
1148 SfxItemSet
* SfxShell::CreateItemSet( sal_uInt16
)
1153 void SfxShell::ApplyItemSet( sal_uInt16
, const SfxItemSet
& )
1157 void SfxShell::SetContextName (const ::rtl::OUString
& rsContextName
)
1159 pImp
->maContextChangeBroadcaster
.Initialize(rsContextName
);
1162 void SfxShell::SetViewShell_Impl( SfxViewShell
* pView
)
1164 pImp
->pViewSh
= pView
;
1167 void SfxShell::BroadcastContextForActivation (const bool bIsActivated
)
1169 SfxViewFrame
* pViewFrame
= GetFrame();
1170 if (pViewFrame
!= NULL
)
1173 pImp
->maContextChangeBroadcaster
.Activate(pViewFrame
->GetFrame().GetFrameInterface());
1175 pImp
->maContextChangeBroadcaster
.Deactivate(pViewFrame
->GetFrame().GetFrameInterface());
1179 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */