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: shell.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"
33 #include <com/sun/star/embed/VerbDescriptor.hpp>
34 #include <com/sun/star/embed/VerbAttributes.hpp>
35 #include <basic/sbstar.hxx>
36 #include <svtools/itempool.hxx>
37 #include <svtools/undo.hxx>
38 #include <svtools/itemdel.hxx>
39 #include <svtools/asynclink.hxx>
40 #include <basic/sbx.hxx>
42 #include <svtools/undoopt.hxx>
47 #include <sfx2/app.hxx>
48 #include <sfx2/shell.hxx>
49 #include <sfx2/bindings.hxx>
50 #include <sfx2/dispatch.hxx>
51 #include <sfx2/viewfrm.hxx>
52 #include "sfxbasic.hxx"
53 #include <sfx2/objface.hxx>
54 #include <sfx2/objsh.hxx>
55 #include <sfx2/viewsh.hxx>
56 #include <sfx2/dispatch.hxx>
57 #include "sfxtypes.hxx"
58 #include <sfx2/request.hxx>
59 #include <sfx2/mnumgr.hxx>
60 #include "statcach.hxx"
61 #include <sfx2/macrconf.hxx>
62 #include <sfx2/msgpool.hxx>
64 //====================================================================
68 //====================================================================
72 //====================================================================
73 typedef SfxSlot
* SfxSlotPtr
;
74 SV_DECL_PTRARR_DEL( SfxVerbSlotArr_Impl
, SfxSlotPtr
, 4, 4)
75 SV_IMPL_PTRARR( SfxVerbSlotArr_Impl
, SfxSlotPtr
);
77 using namespace com::sun::star
;
79 //=========================================================================
81 //=========================================================================
82 struct SfxShell_Impl
: public SfxBroadcaster
84 String aObjectName
;// Name des Sbx-Objects
85 SfxItemArray_Impl aItems
; // Datenaustausch auf Item-Basis
86 SfxViewShell
* pViewSh
; // SfxViewShell falls Shell ViewFrame/ViewShell/SubShell ist
87 SfxViewFrame
* pFrame
; // Frame, falls <UI-aktiv>
88 SfxRepeatTarget
* pRepeatTarget
;
89 // SbxObjectRef xParent;
94 svtools::AsynchronLink
* pExecuter
;
95 svtools::AsynchronLink
* pUpdater
;
96 SfxVerbSlotArr_Impl aSlotArr
;
97 com::sun::star::uno::Sequence
< com::sun::star::embed::VerbDescriptor
> aVerbList
;
98 SfxShell_Impl() : pExecuter( 0 ), pUpdater( 0 ) {}
99 ~SfxShell_Impl() { delete pExecuter
; delete pUpdater
;}
102 //====================================================================
105 String
SfxShellIdent_Impl( const SfxShell
*pSh
)
109 Interne Hilfesfunktion. Liefert einen die SfxShell 'pSh' beschreibenden
110 String zur"uck. Z.B.: SfxApplication[StarWriter]
114 String
aIdent( pSh
->ISA(SfxApplication
) ? DEFINE_CONST_UNICODE("SfxApplication") :
115 pSh
->ISA(SfxViewFrame
) ? DEFINE_CONST_UNICODE("SfxViewFrame") :
116 pSh
->ISA(SfxViewShell
) ? DEFINE_CONST_UNICODE("SfxViewShell") :
117 pSh
->ISA(SfxObjectShell
) ? DEFINE_CONST_UNICODE("SfxObjectShell") : DEFINE_CONST_UNICODE("SfxShell") );
119 aIdent
+= pSh
->GetName();
125 //====================================================================
127 //=========================================================================
129 //=========================================================================
131 void __EXPORT
SfxShell::EmptyExecStub(SfxShell
*, SfxRequest
&)
135 void __EXPORT
SfxShell::EmptyStateStub(SfxShell
*, SfxItemSet
&)
143 Der Konstruktor der Klasse SfxShell initialisierung nur einfache
144 Typen, das dazugeh"orige SbxObject wird erst on-demand erzeugt.
145 Daher ist das Anlegen einer SfxShell Instanz sehr billig.
152 DBG_CTOR(SfxShell
, 0);
153 pImp
= new SfxShell_Impl
;
156 pImp
->pRepeatTarget
= 0;
157 pImp
->bInAppBASIC
= FALSE
;
159 pImp
->bActive
= FALSE
;
160 pImp
->nDisableFlags
= 0;
163 //-------------------------------------------------------------------------
165 SfxShell::SfxShell( SfxViewShell
*pViewSh
)
169 Der Konstruktor der Klasse SfxShell initialisierung nur einfache
170 Typen, das dazugeh"orige SbxObject wird erst on-demand erzeugt.
171 Daher ist das Anlegen einer SfxShell Instanz sehr billig.
178 DBG_CTOR(SfxShell
, 0);
179 pImp
= new SfxShell_Impl
;
180 pImp
->pViewSh
= pViewSh
;
182 pImp
->pRepeatTarget
= 0;
183 pImp
->bInAppBASIC
= FALSE
;
185 pImp
->bActive
= FALSE
;
188 //--------------------------------------------------------------------
190 SfxShell::~SfxShell()
194 Die Verbindungs zu einem ggf. zugeh"origen SbxObject wird gel"ost.
195 Das SbxObject existiert ggf. weiter, kann aber keine Funktionen
196 mehr ausf"uhren und keine Properties mehr bereitstellen.
200 DBG_DTOR(SfxShell
, 0);
204 //--------------------------------------------------------------------
206 void SfxShell::SetName( const String
&rName
)
210 Setzt den Namen des Shell-Objekts. Mit diesem Namen kann die
211 SfxShell-Instanz vom BASIC aus angesprochen werden.
215 pImp
->aObjectName
= rName
;
218 //--------------------------------------------------------------------
220 const String
& SfxShell::GetName() const
224 Liefert den Namen des Shell-Objekts. Mit diesem Namen kann die
225 SfxShell-Instanz vom BASIC aus angesprochen werden.
229 return pImp
->aObjectName
;
232 //--------------------------------------------------------------------
234 SvGlobalName
SfxShell::GetGlobalName() const
238 Liefert den Global Unique Identifier des Shell-Objekts. Mit diesem
239 Namen kann die SfxShell-Instanz z.B. via OLE Automation angesprochen
240 werden, bzw. in der Registration-Database gefunden werden.
244 return SvGlobalName();
247 //--------------------------------------------------------------------
249 SfxDispatcher
* SfxShell::GetDispatcher() const
253 Diese Methode liefert einen Pointer auf den <SfxDispatcher>, in
254 dem die SfxShell gerade <UI-aktiv> ist bzw. einen 0-Pointer, wenn
255 sie gerade nicht UI-aktiv ist.
257 Der zur"uckgegebene Pointer ist nur im unmittelbaren Kontext des
258 Methodenaufrufs g"ultig.
262 return pImp
->pFrame
? pImp
->pFrame
->GetDispatcher() : 0;
265 //--------------------------------------------------------------------
267 SfxViewShell
* SfxShell::GetViewShell() const
271 Liefert bei SubShells die SfxViewShell, in der sie liegen. Sonst und
272 falls nicht vom App-Entwickler angegeben liefert diese Methode 0.
276 return pImp
->pViewSh
;
279 //--------------------------------------------------------------------
281 SfxViewFrame
* SfxShell::GetFrame() const
285 Diese Methode liefert einen Pointer auf den <SfxViewFrame>, dem diese
286 SfxShell-Instanz zugeordnet ist oder in dem sie zur Zeit <UI-aktiv> ist.
287 Ein 0-Pointer wird geliefert, wenn diese SfxShell-OInstanz gerade nicht
288 UI-aktiv ist und auch keinem SfxViewFrame fest zugeordnet ist.
290 Der zur"uckgegebene Pointer ist nur im unmittelbaren Kontext des
291 Methodenaufrufs g"ultig.
296 Nur Instanzen von Subklasse von SfxApplication und SfxObjectShell sollten
297 hier einen 0-Pointer liefern. Ansonsten liegt ein Fehler im Anwendungs-
298 programm vor (falscher Ctor von SfxShell gerufen).
303 <SfxViewShell::GetViewFrame()const>
310 return pImp
->pViewSh
->GetViewFrame();
314 //--------------------------------------------------------------------
316 const SfxPoolItem
* SfxShell::GetItem
318 USHORT nSlotId
// Slot-Id des zu erfragenden <SfxPoolItem>s
323 Mit dieser Methode kann auf beliebige Objekte von Subklassen von
324 <SfxPoolItem> zugegriffen werden. Diese Austauschtechnik wird ben"otigt,
325 wenn z.B. spezielle <SfxToolBoxControl> Subklassen Zugriff auf
326 bestimmte Daten z.B. der <SfxObjectShell> ben"otigen.
328 Die zur"uckgelieferte Instanz geh"ort der jeweilige SfxShell und
329 darf nur im unmittelbaren Kontext des Methodenaufrufs verwendet werden.
334 <SfxShell::PutItem(const SfxPoolItem&)>
335 <SfxShell::RemoveItem(USHORT)>
339 for ( USHORT nPos
= 0; nPos
< pImp
->aItems
.Count(); ++nPos
)
340 if ( pImp
->aItems
.GetObject(nPos
)->Which() == nSlotId
)
341 return pImp
->aItems
.GetObject(nPos
);
345 //--------------------------------------------------------------------
347 void SfxShell::RemoveItem
349 USHORT nSlotId
// Slot-Id des zu l"oschenden <SfxPoolItem>s
354 Mit dieser Methode k"onnen die allgemein zur Verf"ugung gestellten
355 Instanzen von Subklassen von <SfxPoolItem> aus der SfxShell entfernt
358 Die gespeicherte Instanz wird gel"oscht.
363 <SfxShell::PutItem(const SfxPoolItem&)>
364 <SfxShell::GetItem(USHORT)>
368 for ( USHORT nPos
= 0; nPos
< pImp
->aItems
.Count(); ++nPos
)
369 if ( pImp
->aItems
.GetObject(nPos
)->Which() == nSlotId
)
371 // Item entfernen und l"oschen
372 SfxPoolItem
*pItem
= pImp
->aItems
.GetObject(nPos
);
374 pImp
->aItems
.Remove(nPos
);
376 // falls aktiv Bindings benachrichtigen
377 SfxDispatcher
*pDispat
= GetDispatcher();
380 SfxVoidItem
aVoid( nSlotId
);
381 pDispat
->GetBindings()->Broadcast( SfxPoolItemHint( &aVoid
) );
386 //--------------------------------------------------------------------
388 void SfxShell::PutItem
390 const SfxPoolItem
& rItem
/* Instanz, von der eine Kopie erstellt wird,
391 die in der SfxShell in einer Liste
397 Mit dieser Methode k"onnen beliebige Objekte von Subklassen von
398 <SfxPoolItem> zur Verf"ugung gestellt werden. Diese Austauschtechnik
399 wird ben"otigt, wenn z.B. spezielle <SfxToolBoxControl> Subklassen
400 Zugriff auf bestimmte Daten z.B. der <SfxObjectShell> ben"otigen.
402 Falls ein SfxPoolItem mit derselben Slot-Id exisitert, wird dieses
403 automatisch gel"oscht.
408 <SfxShell::RemoveItem(USHORT)>
409 <SfxShell::GetItem(USHORT)>
413 DBG_ASSERT( !rItem
.ISA(SfxSetItem
), "SetItems aren't allowed here" );
414 DBG_ASSERT( SfxItemPool::IsSlot( rItem
.Which() ),
415 "items with Which-Ids aren't allowed here" );
417 // MSC auf WNT/W95 machte hier Mist, Vorsicht bei Umstellungen
418 const SfxPoolItem
*pItem
= rItem
.Clone();
419 SfxPoolItemHint
aItemHint( (SfxPoolItem
*) pItem
);
420 const USHORT nWhich
= rItem
.Which();
421 SfxPoolItem
**ppLoopItem
= (SfxPoolItem
**) pImp
->aItems
.GetData();
423 for ( nPos
= 0; nPos
< pImp
->aItems
.Count(); ++nPos
, ++ppLoopItem
)
425 if ( (*ppLoopItem
)->Which() == nWhich
)
429 pImp
->aItems
.Remove(nPos
);
430 pImp
->aItems
.Insert( (SfxPoolItemPtr
) pItem
, nPos
);
432 // falls aktiv Bindings benachrichtigen
433 SfxDispatcher
*pDispat
= GetDispatcher();
436 SfxBindings
* pBindings
= pDispat
->GetBindings();
437 pBindings
->Broadcast( aItemHint
);
438 USHORT nSlotId
= nWhich
; //pItem->GetSlotId();
439 SfxStateCache
* pCache
= pBindings
->GetStateCache( nSlotId
);
442 pCache
->SetState( SFX_ITEM_AVAILABLE
, pItem
->Clone(), TRUE
);
443 pCache
->SetCachedState( TRUE
);
450 Broadcast( aItemHint
);
451 pImp
->aItems
.Insert((SfxPoolItemPtr
)pItem
, nPos
);
454 //--------------------------------------------------------------------
456 SfxInterface
* SfxShell::GetInterface() const
460 Mit dieser virtuellen Methode, die durch das Makro <SFX_DECL_INTERFACE>
461 von jeder Subclass mit eigenen Slots automatisch "uberladen wird, kann
462 auf die zu der Subklasse geh"orende <SfxInterface>-Instanz zugegriffen
465 Die Klasse SfxShell selbst hat noch kein eigenes SfxInterface
466 (keine Slots), daher wird ein 0-Pointer zur"uckgeliefert.
470 return GetStaticInterface();
473 //--------------------------------------------------------------------
475 SfxBroadcaster
* SfxShell::GetBroadcaster()
479 Liefert einen SfxBroadcaster f"ur diese SfxShell-Instanz bis die
480 Klasse SfxShell von SfxBroadcaster abgeleitet ist.
487 //--------------------------------------------------------------------
489 SfxUndoManager
* SfxShell::GetUndoManager()
493 Jede Subclass von SfxShell kann "uber einen <SfxUndoManager> verf"ugen.
494 Dieser kann in den abgeleiteten Klasse mit <SfxShell:SetUndoManager()>
497 Die Klasse SfxShell selbst hat noch keinen SfxUndoManager, es wird
498 daher ein 0-Pointer zur"uckgeliefert.
505 //--------------------------------------------------------------------
507 void SfxShell::SetUndoManager( SfxUndoManager
*pNewUndoMgr
)
511 Setzt einen <SfxUndoManager> f"ur diese <SfxShell> Instanz. F"ur das
512 Undo wird immer nur der Undo-Manager an der jeweils oben auf dem
513 Stack des <SfxDispatcher> liegenden SfxShell verwendet.
515 Am "ubergebenen <SfxUndoManager> wird automatisch die aktuelle
516 Max-Undo-Action-Count Einstellung aus den Optionen gesetzt.
518 'pNewUndoMgr' mu\s bis zum Dtor dieser SfxShell-Instanz oder bis
519 zum n"achsten 'SetUndoManager()' existieren.
523 pUndoMgr
= pNewUndoMgr
;
525 pUndoMgr
->SetMaxUndoActionCount( (USHORT
) SvtUndoOptions().GetUndoCount() );
528 //--------------------------------------------------------------------
530 SfxRepeatTarget
* SfxShell::GetRepeatTarget() const
534 Liefert einen Pointer auf die <SfxRepeatTarget>-Instanz, die
535 als RepeatTarget bei SID_REPEAT verwendet wird, wenn der
536 von dieser SfxShell gelieferte <SfxUndoManager> angesprochen wird.
537 Der R"uckgabewert kann 0 sein.
542 Eine Ableitung von <SfxShell> oder einer ihrer Subklassen von
543 <SfxRepeatTarget> ist nicht zu empfehlen, da Compiler-Fehler
544 provoziert werden (wegen Call-to-Pointer-to-Member-Function to
549 return pImp
->pRepeatTarget
;
552 //--------------------------------------------------------------------
554 void SfxShell::SetRepeatTarget( SfxRepeatTarget
*pTarget
)
558 Setzt den die <SfxRepeatTarget>-Instanz, die bei SID_REPEAT als
559 RepeatTarget verwendet wird, wenn der von dieser SfxShell gelieferte
560 <SfxUndoManager> angesprochen wird. Durch 'pTarget==0' wird SID_REPEAT
561 f"ur diese SfxShell disabled. Die Instanz '*pTarget' mu\s so lange
562 leben, wie sie angemeldet ist.
567 Eine Ableitung von <SfxShell> oder einer ihrer Subklassen von
568 <SfxRepeatTarget> ist nicht zu empfehlen, da Compiler-Fehler
569 provoziert werden (wegen Call-to-Pointer-to-Member-Function to
574 pImp
->pRepeatTarget
= pTarget
;
577 //--------------------------------------------------------------------
579 void SfxShell::Invalidate
581 USHORT nId
/* Zu invalidierende Slot-Id oder Which-Id.
582 Falls diese 0 ist (default), werden
583 alle z.Zt. von dieser Shell bedienten
584 Slot-Ids invalidiert. */
589 Mit dieser Methode k"onnen Slots der Subclasses "uber die Slot-Id
590 oder alternativ "uber die Which-Id invalidiert werden. Slot-Ids,
591 die von der Subclass ererbt sind, werden ebenfalls invalidert.
594 <SfxBindings::Invalidate(USHORT)>
595 <SfxBindings::InvalidateAll(BOOL)>
599 if ( !GetViewShell() )
601 DBG_ERROR( "wrong Invalidate method called!" );
605 Invalidate_Impl( GetViewShell()->GetViewFrame()->GetBindings(), nId
);
608 void SfxShell::Invalidate_Impl( SfxBindings
& rBindings
, USHORT nId
)
612 rBindings
.InvalidateShell( *this, FALSE
);
616 const SfxInterface
*pIF
= GetInterface();
619 const SfxSlot
*pSlot
= pIF
->GetSlot(nId
);
622 // bei Enum-Slots ist der Master-Slot zu invalidieren
623 if ( SFX_KIND_ENUM
== pSlot
->GetKind() )
624 pSlot
= pSlot
->GetLinkedSlot();
626 // den Slot selbst und ggf. auch alle Slave-Slots invalidieren
627 rBindings
.Invalidate( pSlot
->GetSlotId() );
628 for ( const SfxSlot
*pSlave
= pSlot
->GetLinkedSlot();
629 pSlave
&& pIF
->ContainsSlot_Impl( pSlave
) &&
630 pSlave
->GetLinkedSlot() == pSlot
;
632 rBindings
.Invalidate( pSlave
->GetSlotId() );
637 pIF
= pIF
->GetGenoType();
642 DBG_WARNING( "W3: invalidating slot-id unknown in shell" );
646 //--------------------------------------------------------------------
648 void SfxShell::DoActivate_Impl( SfxViewFrame
*pFrame
, BOOL bMDI
)
652 Diese Methode steuert die Aktivierung der SfxShell-Instanz. Zun"achst
653 wird durch Aufruf der virtuellen Methode <SfxShell::Activate(BOOL)>
654 der Subclass die M"oglichkeit gegeben, auf das Event zu reagieren.
656 Bei bMDI == TRUE wird das zugeh"orige SbxObject 'scharfgeschaltet',
657 so da\s Methoden des Objekts unqualifiziert (ohne den Namen des Objekts)
658 vom BASIC gefunden werden.
663 const SfxInterface
*p_IF
= GetInterface();
668 String
aMsg("SfxShell::DoActivate() ");
671 aMsg
+= GetInterface()->GetName();
673 if ( bMDI
) aMsg
+= "MDI";
674 DbgTrace( aMsg
.GetBuffer() );
679 // Frame merken, in dem aktiviert wird
680 pImp
->pFrame
= pFrame
;
681 pImp
->bActive
= TRUE
;
684 // Subklasse benachrichtigen
688 //--------------------------------------------------------------------
690 void SfxShell::DoDeactivate_Impl( SfxViewFrame
*pFrame
, BOOL bMDI
)
694 Diese Methode steuert die Deaktivierung der SfxShell-Instanz. Bei
695 bMDI == TRUE wird zun"achst das SbxObject in einen Status versetzt,
696 so da\s Methoden vom BASIC aus nur noch qualifiziert gerufen werden
699 Dann erh"alt in jedem Fall die Subclass durch Aufruf der virtuellen
700 Methode <SfxShell::Deactivate(BOOL)> die M"oglichkeit auf das Event
706 const SfxInterface
*p_IF
= GetInterface();
711 String
aMsg("SfxShell::DoDeactivate()");
714 aMsg
+= GetInterface()->GetName();
716 if ( bMDI
) aMsg
+= "MDI";
717 DbgTrace( aMsg
.GetBuffer() );
720 // nur wenn er vom Frame kommt (nicht z.B. pop der BASIC-IDE vom AppDisp)
721 if ( bMDI
&& pImp
->pFrame
== pFrame
)
725 pImp
->bActive
= FALSE
;
728 // Subklasse benachrichtigen
732 //--------------------------------------------------------------------
734 BOOL
SfxShell::IsActive() const
736 return pImp
->bActive
;
739 //--------------------------------------------------------------------
741 void SfxShell::Activate
743 BOOL
/*bMDI*/ /* TRUE
744 der <SfxDispatcher>, auf dem die SfxShell sich
745 befindet, ist aktiv geworden oder die SfxShell
746 Instanz wurde auf einen aktiven SfxDispatcher
747 gepusht. (vergl. SystemWindow::IsMDIActivate())
750 das zum <SfxViewFrame>, auf dessen SfxDispatcher
751 sich die SfxShell Instanz befindet, wurde
753 (z.B. durch einen geschlossenen Dialog) */
758 Virtuelle Methode, die beim Aktivieren der SfxShell Instanz gerufen
759 wird, um den Subclasses die Gelegenheit zu geben, auf das Aktivieren
762 Die Basisimplementation ist leer und braucht nicht gerufen zu werden.
766 StarView SystemWindow::Activate(BOOL)
772 //--------------------------------------------------------------------
774 void SfxShell::Deactivate
776 BOOL
/*bMDI*/ /* TRUE
777 der <SfxDispatcher>, auf dem die SfxShell sich
778 befindet, ist inaktiv geworden oder die SfxShell
779 Instanz wurde auf einen aktiven SfxDispatcher
780 gepoppt. (vergl. SystemWindow::IsMDIActivate())
783 das zum <SfxViewFrame>, auf dessen SfxDispatcher
784 sich die SfxShell Instanz befindet, wurde
785 deaktiviert. (z.B. durch einen Dialog) */
791 Virtuelle Methode, die beim Deaktivieren der SfxShell Instanz gerufen
792 wird, um den Subclasses die Gelegenheit zu geben, auf das Deaktivieren
795 Die Basisimplementation ist leer und braucht nicht gerufen zu werden.
799 StarView SystemWindow::Dectivate(BOOL)
805 void SfxShell::ParentActivate
811 Ein Parent des <SfxDispatcher>, auf dem die SfxShell sich befindet,
812 ist aktiv geworden, oder die SfxShell Instanz wurde auf einen
813 <SfxDispatcher> gepusht, dessen parent aktiv ist.
815 Die Basisimplementation ist leer und braucht nicht gerufen zu werden.
823 //--------------------------------------------------------------------
825 void SfxShell::ParentDeactivate
831 Der aktive Parent des <SfxDispatcher>, auf dem die SfxShell sich befindet,
832 ist deaktiviert worden.
834 Die Basisimplementation ist leer und braucht nicht gerufen zu werden.
837 SfxShell::Deactivate()
842 //--------------------------------------------------------------------
844 ResMgr
* SfxShell::GetResMgr() const
848 Diese Methode liefert den ResMgr der <Resource-DLL>, die von der
849 SfxShell-Instanz verwendet wird. Ist dies ein 0-Pointer, so
850 ist der aktuelle Resource-Manager zu verwenden.
854 return GetInterface()->GetResMgr();
857 //--------------------------------------------------------------------
859 FASTBOOL
SfxShell::CanExecuteSlot_Impl( const SfxSlot
&rSlot
)
863 Diese Methode stellt durch Aufruf der Statusfunktion fest,
864 ob 'rSlot' aktuell ausgef"uhrt werden kann.
868 SfxItemPool
&rPool
= GetPool();
869 const USHORT nId
= rSlot
.GetWhich( rPool
);
870 SfxItemSet
aSet(rPool
, nId
, nId
);
871 SfxStateFunc pFunc
= rSlot
.GetStateFnc();
872 CallState( pFunc
, aSet
);
873 return aSet
.GetItemState(nId
) != SFX_ITEM_DISABLED
;
876 //--------------------------------------------------------------------
878 long ShellCall_Impl( void* pObj
, void* pArg
)
880 ((SfxShell
* )pObj
)->ExecuteSlot( *(SfxRequest
*)pArg
, (SfxInterface
*)0L );
885 Asynchrones ExecuteSlot fuer das RELOAD
888 //--------------------------------------------------------------------
889 const SfxPoolItem
* SfxShell::ExecuteSlot( SfxRequest
& rReq
, BOOL bAsync
)
892 return ExecuteSlot( rReq
, (SfxInterface
*)0L );
895 if( !pImp
->pExecuter
)
896 pImp
->pExecuter
= new svtools::AsynchronLink(
897 Link( this, ShellCall_Impl
) );
898 pImp
->pExecuter
->Call( new SfxRequest( rReq
) );
903 const SfxPoolItem
* SfxShell::ExecuteSlot
905 SfxRequest
&rReq
, // der weiterzuleitende <SfxRequest>
906 const SfxInterface
* pIF
// default = 0 bedeutet virtuell besorgen
911 Diese Methode erm"oglicht das Weiterleiten eines <SfxRequest> an
912 die angegebene Basis-<SfxShell>.
917 In einer von SfxViewShell abgeleiteten Klasse soll SID_PRINTDOCDIRECT
918 abgefangen werden. Unter bestimmten Umst"anden soll vor dem Drucken
919 eine Abfrage erscheinen, und der Request soll ggf. abgebrochen werden.
921 Dazu ist in der IDL dieser Subklasse der o.g. Slot einzutragen. Die
922 Execute-Methode enth"alt dann skizziert:
924 void SubViewShell::Exec( SfxRequest &rReq )
926 if ( rReq.GetSlot() == SID_PRINTDOCDIRECT )
930 ExecuteSlot( rReq, SfxViewShell::GetInterface() );
934 Es braucht i.d.R. kein rReq.Done() gerufen zu werden, da das bereits
935 die Implementierung der SfxViewShell erledigt bzw. abgebrochen wurde.
940 <SfxShell::GetSlotState(USHORT,const SfxInterface*,SfxItemSet*)>
945 pIF
= GetInterface();
947 USHORT nSlot
= rReq
.GetSlot();
948 const SfxSlot
* pSlot
= NULL
;
949 if ( nSlot
>= SID_VERB_START
&& nSlot
<= SID_VERB_END
)
950 pSlot
= GetVerbSlot_Impl(nSlot
);
952 pSlot
= pIF
->GetSlot(nSlot
);
953 if ( !pSlot
&& SfxMacroConfig::IsMacroSlot( nSlot
) )
955 SfxMacroInfo
* pInfo
= SFX_APP()->GetMacroConfig()->GetMacroInfo(nSlot
);
957 pSlot
= pInfo
->GetSlot();
960 DBG_ASSERT( pSlot
, "slot not supported" );
962 SfxExecFunc pFunc
= pSlot
->GetExecFnc();
964 CallExec( pFunc
, rReq
);
966 return rReq
.GetReturnValue();
969 //--------------------------------------------------------------------
971 const SfxPoolItem
* SfxShell::GetSlotState
973 USHORT nSlotId
, // Slot-Id des zu befragenden Slots
974 const SfxInterface
* pIF
, // default = 0 bedeutet virtuell besorgen
975 SfxItemSet
* pStateSet
// SfxItemSet der Slot-State-Methode
980 Diese Methode liefert den Status des Slots mit der angegebenen Slot-Id
981 "uber das angegebene Interface.
983 Ist der Slot disabled oder in dieser SfxShell (und deren Parent-Shells)
984 nicht bekannt, wird ein 0-Pointer zur"uckgeliefert.
986 Hat der Slot keinen Status, wird ein SfxVoidItem zur"uckgeliefert.
988 Der Status wird bei pStateSet != 0 gleich in diesem Set gesetzt, so
989 da\s <SfxShell>-Subklassen Slots-"uberladen und auch bei der
990 Status-Methode die Basis-Implementierung rufen k"onnen.
995 In einer von SfxViewShell abgeleiteten Klasse soll SID_PRINTDOCDIRECT
996 abgefangen werden. Unter bestimmten Umst"anden soll vor dem Drucken
997 eine Abfrage erscheinen, und der Request soll ggf. abgebrochen werden.
999 Dazu ist in der IDL dieser Subklasse der o.g. Slot einzutragen. Die
1000 Status-Methode enth"alt dann skizziert:
1002 void SubViewShell::PrintState( SfxItemSet &rState )
1004 if ( rState.GetItemState( SID_PRINTDOCDIRECT ) != SFX_ITEM_UNKNOWN )
1005 GetSlotState( SID_PRINTDOCDIRECT, SfxViewShell::GetInterface(),
1013 <SfxShell::ExecuteSlot(SfxRequest&)>
1017 // Slot am angegebenen Interface besorgen
1019 pIF
= GetInterface();
1020 SfxItemState eState
;
1021 SfxItemPool
&rPool
= GetPool();
1023 const SfxSlot
* pSlot
= NULL
;
1024 if ( nSlotId
>= SID_VERB_START
&& nSlotId
<= SID_VERB_END
)
1025 pSlot
= GetVerbSlot_Impl(nSlotId
);
1027 pSlot
= pIF
->GetSlot(nSlotId
);
1028 if ( !pSlot
&& SfxMacroConfig::IsMacroSlot( nSlotId
) )
1030 SfxMacroInfo
* pInfo
= SFX_APP()->GetMacroConfig()->GetMacroInfo(nSlotId
);
1032 pSlot
= pInfo
->GetSlot();
1036 // ggf. auf Which-Id mappen
1037 nSlotId
= pSlot
->GetWhich( rPool
);
1039 // Item und Item-Status besorgen
1040 const SfxPoolItem
*pItem
= NULL
;
1041 SfxItemSet
aSet( rPool
, nSlotId
, nSlotId
); // pItem stirbt sonst zu fr"uh
1044 // Status-Methode rufen
1045 SfxStateFunc pFunc
= pSlot
->GetStateFnc();
1047 CallState( pFunc
, aSet
);
1048 eState
= aSet
.GetItemState( nSlotId
, TRUE
, &pItem
);
1050 // ggf. Default-Item besorgen
1051 if ( eState
== SFX_ITEM_DEFAULT
)
1053 if ( SfxItemPool::IsWhich(nSlotId
) )
1054 pItem
= &rPool
.GetDefaultItem(nSlotId
);
1056 eState
= SFX_ITEM_DONTCARE
;
1060 eState
= SFX_ITEM_UNKNOWN
;
1062 // Item und Item-Status auswerten und ggf. in pStateSet mitpflegen
1063 SfxPoolItem
*pRetItem
= 0;
1064 if ( eState
<= SFX_ITEM_DISABLED
)
1067 pStateSet
->DisableItem(nSlotId
);
1070 else if ( eState
== SFX_ITEM_DONTCARE
)
1073 pStateSet
->ClearItem(nSlotId
);
1074 pRetItem
= new SfxVoidItem(0);
1078 if ( pStateSet
&& pStateSet
->Put( *pItem
) )
1079 return &pStateSet
->Get( pItem
->Which() );
1080 pRetItem
= pItem
->Clone();
1082 DeleteItemOnIdle(pRetItem
);
1087 //--------------------------------------------------------------------
1089 SFX_EXEC_STUB(SfxShell
, VerbExec
)
1090 SFX_STATE_STUB(SfxShell
, VerbState
)
1092 void SfxShell::SetVerbs(const com::sun::star::uno::Sequence
< com::sun::star::embed::VerbDescriptor
>& aVerbs
)
1094 SfxViewShell
*pViewSh
= PTR_CAST ( SfxViewShell
, this);
1096 DBG_ASSERT(pViewSh
, "SetVerbs nur an der ViewShell aufrufen!");
1100 // Zun"achst alle Statecaches dirty machen, damit keiner mehr versucht,
1101 // die Slots zu benutzen
1103 SfxBindings
*pBindings
=
1104 pViewSh
->GetViewFrame()->GetDispatcher()->GetBindings();
1105 USHORT nCount
= pImp
->aSlotArr
.Count();
1106 for (USHORT n1
=0; n1
<nCount
; n1
++)
1108 USHORT nId
= SID_VERB_START
+ n1
;
1109 pBindings
->Invalidate(nId
, FALSE
, TRUE
);
1114 for (sal_Int32 n
=0; n
<aVerbs
.getLength(); n
++)
1116 USHORT nSlotId
= SID_VERB_START
+ nr
++;
1117 DBG_ASSERT(nSlotId
<= SID_VERB_END
, "Zuviele Verben!");
1118 if (nSlotId
> SID_VERB_END
)
1121 SfxSlot
*pNewSlot
= new SfxSlot
;
1122 pNewSlot
->nSlotId
= nSlotId
;
1123 pNewSlot
->nGroupId
= 0;
1125 // Verb-Slots m"ussen asynchron ausgef"uhrt werden, da sie w"ahrend
1126 // des Ausf"uhrens zerst"ort werden k"onnten
1127 pNewSlot
->nFlags
= SFX_SLOT_ASYNCHRON
| SFX_SLOT_CONTAINER
;
1128 pNewSlot
->nMasterSlotId
= 0;
1129 pNewSlot
->nValue
= 0;
1130 pNewSlot
->fnExec
= SFX_STUB_PTR(SfxShell
,VerbExec
);
1131 pNewSlot
->fnState
= SFX_STUB_PTR(SfxShell
,VerbState
);
1132 pNewSlot
->pType
= 0; HACK(SFX_TYPE(SfxVoidItem
))
1133 pNewSlot
->pName
= U2S(aVerbs
[n
].VerbName
);
1134 pNewSlot
->pLinkedSlot
= 0;
1135 pNewSlot
->nArgDefCount
= 0;
1136 pNewSlot
->pFirstArgDef
= 0;
1137 pNewSlot
->pUnoName
= 0;
1139 if (pImp
->aSlotArr
.Count())
1141 SfxSlot
*pSlot
= (pImp
->aSlotArr
)[0];
1142 pNewSlot
->pNextSlot
= pSlot
->pNextSlot
;
1143 pSlot
->pNextSlot
= pNewSlot
;
1146 pNewSlot
->pNextSlot
= pNewSlot
;
1148 pImp
->aSlotArr
.Insert(pNewSlot
, (USHORT
) n
);
1151 pImp
->aVerbList
= aVerbs
;
1155 // Der Status von SID_OBJECT wird im Controller direkt an der Shell
1156 // abgeholt, es reicht also, ein neues StatusUpdate anzuregen
1157 SfxBindings
*pBindings
= pViewSh
->GetViewFrame()->GetDispatcher()->
1159 pBindings
->Invalidate( SID_OBJECT
, TRUE
, TRUE
);
1163 //--------------------------------------------------------------------
1165 const com::sun::star::uno::Sequence
< com::sun::star::embed::VerbDescriptor
>& SfxShell::GetVerbs() const
1167 return pImp
->aVerbList
;
1170 //--------------------------------------------------------------------
1172 void SfxShell::VerbExec(SfxRequest
& rReq
)
1174 USHORT nId
= rReq
.GetSlot();
1175 SfxViewShell
*pViewShell
= GetViewShell();
1178 BOOL bReadOnly
= pViewShell
->GetObjectShell()->IsReadOnly();
1179 com::sun::star::uno::Sequence
< com::sun::star::embed::VerbDescriptor
> aList
= pViewShell
->GetVerbs();
1180 for (sal_Int32 n
=0, nVerb
=0; n
<aList
.getLength(); n
++)
1182 // check for ReadOnly verbs
1183 if ( bReadOnly
&& !(aList
[n
].VerbAttributes
& embed::VerbAttributes::MS_VERBATTR_NEVERDIRTIES
) )
1186 // check for verbs that shouldn't appear in the menu
1187 if ( !(aList
[n
].VerbAttributes
& embed::VerbAttributes::MS_VERBATTR_ONCONTAINERMENU
) )
1190 if (nId
== SID_VERB_START
+ nVerb
++)
1192 pViewShell
->DoVerb(aList
[n
].VerbID
);
1200 //--------------------------------------------------------------------
1202 void SfxShell::VerbState(SfxItemSet
& )
1206 //--------------------------------------------------------------------
1208 const SfxSlot
* SfxShell::GetVerbSlot_Impl(USHORT nId
) const
1210 com::sun::star::uno::Sequence
< com::sun::star::embed::VerbDescriptor
> rList
= pImp
->aVerbList
;
1212 DBG_ASSERT(nId
>= SID_VERB_START
&& nId
<= SID_VERB_END
,"Falsche VerbId!");
1213 USHORT nIndex
= nId
- SID_VERB_START
;
1214 DBG_ASSERT(nIndex
< rList
.getLength(),"Falsche VerbId!");
1216 if (nIndex
< rList
.getLength())
1217 return pImp
->aSlotArr
[nIndex
];
1222 //--------------------------------------------------------------------
1224 void SfxShell::SetHelpId(ULONG nId
)
1226 pImp
->nHelpId
= nId
;
1229 //--------------------------------------------------------------------
1231 ULONG
SfxShell::GetHelpId() const
1233 return pImp
->nHelpId
;
1236 //--------------------------------------------------------------------
1238 SfxObjectShell
* SfxShell::GetObjectShell()
1240 if ( GetViewShell() )
1241 return GetViewShell()->GetViewFrame()->GetObjectShell();
1246 //--------------------------------------------------------------------
1248 sal_Bool
SfxShell::HasUIFeature( sal_uInt32
)
1253 long DispatcherUpdate_Impl( void*, void* pArg
)
1255 ((SfxDispatcher
*) pArg
)->Update_Impl( TRUE
);
1256 ((SfxDispatcher
*) pArg
)->GetBindings()->InvalidateAll(FALSE
);
1260 void SfxShell::UIFeatureChanged()
1262 SfxViewFrame
*pFrame
= GetFrame();
1263 if ( pFrame
&& pFrame
->IsVisible_Impl() )
1265 // Auch dann Update erzwingen, wenn Dispatcher schon geupdated ist,
1266 // sonst bleibt evtl. irgendwas in den gebunkerten Tools stecken.
1267 // Asynchron aufrufen, um Rekursionen zu vermeiden
1268 if ( !pImp
->pUpdater
)
1269 pImp
->pUpdater
= new svtools::AsynchronLink( Link( this, DispatcherUpdate_Impl
) );
1271 // Mehrfachaufrufe gestattet
1272 pImp
->pUpdater
->Call( pFrame
->GetDispatcher(), TRUE
);
1276 void SfxShell::SetDisableFlags( ULONG nFlags
)
1278 pImp
->nDisableFlags
= nFlags
;
1281 ULONG
SfxShell::GetDisableFlags() const
1283 return pImp
->nDisableFlags
;
1286 SfxItemSet
* SfxShell::CreateItemSet( USHORT
)
1291 void SfxShell::ApplyItemSet( USHORT
, const SfxItemSet
& )
1295 void SfxShell::SetViewShell_Impl( SfxViewShell
* pView
)
1297 pImp
->pViewSh
= pView
;