summaryrefslogtreecommitdiff
path: root/sfx2/source/control/shell.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'sfx2/source/control/shell.cxx')
-rw-r--r--sfx2/source/control/shell.cxx1298
1 files changed, 1298 insertions, 0 deletions
diff --git a/sfx2/source/control/shell.cxx b/sfx2/source/control/shell.cxx
new file mode 100644
index 000000000000..f3df5dc36d0c
--- /dev/null
+++ b/sfx2/source/control/shell.cxx
@@ -0,0 +1,1298 @@
+/*************************************************************************
+ *
+ * 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
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sfx2.hxx"
+#include <com/sun/star/embed/VerbDescriptor.hpp>
+#include <com/sun/star/embed/VerbAttributes.hpp>
+#include <basic/sbstar.hxx>
+#include <svl/itempool.hxx>
+#include <svl/undo.hxx>
+#include <svtools/itemdel.hxx>
+#include <svtools/asynclink.hxx>
+#include <basic/sbx.hxx>
+
+#include <unotools/undoopt.hxx>
+
+#ifndef GCC
+#endif
+
+#include <sfx2/app.hxx>
+#include <sfx2/shell.hxx>
+#include <sfx2/bindings.hxx>
+#include <sfx2/dispatch.hxx>
+#include <sfx2/viewfrm.hxx>
+#include "sfxbasic.hxx"
+#include <sfx2/objface.hxx>
+#include <sfx2/objsh.hxx>
+#include <sfx2/viewsh.hxx>
+#include <sfx2/dispatch.hxx>
+#include "sfxtypes.hxx"
+#include <sfx2/request.hxx>
+#include <sfx2/mnumgr.hxx>
+#include "statcach.hxx"
+#include <sfx2/macrconf.hxx>
+#include <sfx2/msgpool.hxx>
+
+//====================================================================
+
+DBG_NAME(SfxShell)
+
+//====================================================================
+
+TYPEINIT0(SfxShell);
+
+//====================================================================
+typedef SfxSlot* SfxSlotPtr;
+SV_DECL_PTRARR_DEL( SfxVerbSlotArr_Impl, SfxSlotPtr, 4, 4)
+SV_IMPL_PTRARR( SfxVerbSlotArr_Impl, SfxSlotPtr);
+
+using namespace com::sun::star;
+
+//=========================================================================
+// SfxShell_Impl
+//=========================================================================
+struct SfxShell_Impl: public SfxBroadcaster
+{
+ String aObjectName;// Name des Sbx-Objects
+ SfxItemArray_Impl aItems; // Datenaustausch auf Item-Basis
+ SfxViewShell* pViewSh; // SfxViewShell falls Shell ViewFrame/ViewShell/SubShell ist
+ SfxViewFrame* pFrame; // Frame, falls <UI-aktiv>
+ SfxRepeatTarget* pRepeatTarget;
+// SbxObjectRef xParent;
+ BOOL bInAppBASIC;
+ BOOL bActive;
+ ULONG nDisableFlags;
+ ULONG 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;}
+};
+
+//====================================================================
+#ifdef DBG_UTIL
+
+String SfxShellIdent_Impl( const SfxShell *pSh )
+
+/* [Beschreibung]
+
+ Interne Hilfesfunktion. Liefert einen die SfxShell 'pSh' beschreibenden
+ String zur"uck. Z.B.: SfxApplication[StarWriter]
+*/
+
+{
+ String aIdent( pSh->ISA(SfxApplication) ? DEFINE_CONST_UNICODE("SfxApplication") :
+ pSh->ISA(SfxViewFrame) ? DEFINE_CONST_UNICODE("SfxViewFrame") :
+ pSh->ISA(SfxViewShell) ? DEFINE_CONST_UNICODE("SfxViewShell") :
+ pSh->ISA(SfxObjectShell) ? DEFINE_CONST_UNICODE("SfxObjectShell") : DEFINE_CONST_UNICODE("SfxShell") );
+ aIdent += '[';
+ aIdent += pSh->GetName();
+ aIdent += ']';
+ return aIdent;
+}
+
+#endif
+//====================================================================
+
+//=========================================================================
+// SfxShell
+//=========================================================================
+
+void __EXPORT SfxShell::EmptyExecStub(SfxShell *, SfxRequest &)
+{
+}
+
+void __EXPORT SfxShell::EmptyStateStub(SfxShell *, SfxItemSet &)
+{
+}
+
+SfxShell::SfxShell()
+
+/* [Beschreibung]
+
+ Der Konstruktor der Klasse SfxShell initialisierung nur einfache
+ Typen, das dazugeh"orige SbxObject wird erst on-demand erzeugt.
+ Daher ist das Anlegen einer SfxShell Instanz sehr billig.
+*/
+
+: 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 = FALSE;
+ pImp->nHelpId = 0L;
+ pImp->bActive = FALSE;
+ pImp->nDisableFlags = 0;
+}
+
+//-------------------------------------------------------------------------
+
+SfxShell::SfxShell( SfxViewShell *pViewSh )
+
+/* [Beschreibung]
+
+ Der Konstruktor der Klasse SfxShell initialisierung nur einfache
+ Typen, das dazugeh"orige SbxObject wird erst on-demand erzeugt.
+ Daher ist das Anlegen einer SfxShell Instanz sehr billig.
+*/
+
+: 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 = FALSE;
+ pImp->nHelpId = 0L;
+ pImp->bActive = FALSE;
+}
+
+//--------------------------------------------------------------------
+
+SfxShell::~SfxShell()
+
+/* [Beschreibung]
+
+ Die Verbindungs zu einem ggf. zugeh"origen SbxObject wird gel"ost.
+ Das SbxObject existiert ggf. weiter, kann aber keine Funktionen
+ mehr ausf"uhren und keine Properties mehr bereitstellen.
+*/
+
+{
+ DBG_DTOR(SfxShell, 0);
+ delete pImp;
+}
+
+//--------------------------------------------------------------------
+
+void SfxShell::SetName( const String &rName )
+
+/* [Beschreibung]
+
+ Setzt den Namen des Shell-Objekts. Mit diesem Namen kann die
+ SfxShell-Instanz vom BASIC aus angesprochen werden.
+*/
+
+{
+ pImp->aObjectName = rName;
+}
+
+//--------------------------------------------------------------------
+
+const String& SfxShell::GetName() const
+
+/* [Beschreibung]
+
+ Liefert den Namen des Shell-Objekts. Mit diesem Namen kann die
+ SfxShell-Instanz vom BASIC aus angesprochen werden.
+*/
+
+{
+ return pImp->aObjectName;
+}
+
+//--------------------------------------------------------------------
+
+SvGlobalName SfxShell::GetGlobalName() const
+
+/* [Beschreibung]
+
+ Liefert den Global Unique Identifier des Shell-Objekts. Mit diesem
+ Namen kann die SfxShell-Instanz z.B. via OLE Automation angesprochen
+ werden, bzw. in der Registration-Database gefunden werden.
+*/
+
+{
+ return SvGlobalName();
+}
+
+//--------------------------------------------------------------------
+
+SfxDispatcher* SfxShell::GetDispatcher() const
+
+/* [Beschreibung]
+
+ Diese Methode liefert einen Pointer auf den <SfxDispatcher>, in
+ dem die SfxShell gerade <UI-aktiv> ist bzw. einen 0-Pointer, wenn
+ sie gerade nicht UI-aktiv ist.
+
+ Der zur"uckgegebene Pointer ist nur im unmittelbaren Kontext des
+ Methodenaufrufs g"ultig.
+*/
+
+{
+ return pImp->pFrame ? pImp->pFrame->GetDispatcher() : 0;
+}
+
+//--------------------------------------------------------------------
+
+SfxViewShell* SfxShell::GetViewShell() const
+
+/* [Beschreibung]
+
+ Liefert bei SubShells die SfxViewShell, in der sie liegen. Sonst und
+ falls nicht vom App-Entwickler angegeben liefert diese Methode 0.
+*/
+
+{
+ return pImp->pViewSh;
+}
+
+//--------------------------------------------------------------------
+
+SfxViewFrame* SfxShell::GetFrame() const
+
+/* [Beschreibung]
+
+ Diese Methode liefert einen Pointer auf den <SfxViewFrame>, dem diese
+ SfxShell-Instanz zugeordnet ist oder in dem sie zur Zeit <UI-aktiv> ist.
+ Ein 0-Pointer wird geliefert, wenn diese SfxShell-OInstanz gerade nicht
+ UI-aktiv ist und auch keinem SfxViewFrame fest zugeordnet ist.
+
+ Der zur"uckgegebene Pointer ist nur im unmittelbaren Kontext des
+ Methodenaufrufs g"ultig.
+
+
+ [Anmerkung]
+
+ Nur Instanzen von Subklasse von SfxApplication und SfxObjectShell sollten
+ hier einen 0-Pointer liefern. Ansonsten liegt ein Fehler im Anwendungs-
+ programm vor (falscher Ctor von SfxShell gerufen).
+
+
+ [Querverweise]
+
+ <SfxViewShell::GetViewFrame()const>
+*/
+
+{
+ if ( pImp->pFrame )
+ return pImp->pFrame;
+ if ( pImp->pViewSh )
+ return pImp->pViewSh->GetViewFrame();
+ return 0;
+}
+
+//--------------------------------------------------------------------
+
+const SfxPoolItem* SfxShell::GetItem
+(
+ USHORT nSlotId // Slot-Id des zu erfragenden <SfxPoolItem>s
+) const
+
+/* [Beschreibung]
+
+ Mit dieser Methode kann auf beliebige Objekte von Subklassen von
+ <SfxPoolItem> zugegriffen werden. Diese Austauschtechnik wird ben"otigt,
+ wenn z.B. spezielle <SfxToolBoxControl> Subklassen Zugriff auf
+ bestimmte Daten z.B. der <SfxObjectShell> ben"otigen.
+
+ Die zur"uckgelieferte Instanz geh"ort der jeweilige SfxShell und
+ darf nur im unmittelbaren Kontext des Methodenaufrufs verwendet werden.
+
+
+ [Querverweise]
+
+ <SfxShell::PutItem(const SfxPoolItem&)>
+ <SfxShell::RemoveItem(USHORT)>
+*/
+
+{
+ for ( USHORT nPos = 0; nPos < pImp->aItems.Count(); ++nPos )
+ if ( pImp->aItems.GetObject(nPos)->Which() == nSlotId )
+ return pImp->aItems.GetObject(nPos);
+ return 0;
+}
+
+//--------------------------------------------------------------------
+
+void SfxShell::RemoveItem
+(
+ USHORT nSlotId // Slot-Id des zu l"oschenden <SfxPoolItem>s
+)
+
+/* [Beschreibung]
+
+ Mit dieser Methode k"onnen die allgemein zur Verf"ugung gestellten
+ Instanzen von Subklassen von <SfxPoolItem> aus der SfxShell entfernt
+ werden.
+
+ Die gespeicherte Instanz wird gel"oscht.
+
+
+ [Querverweise]
+
+ <SfxShell::PutItem(const SfxPoolItem&)>
+ <SfxShell::GetItem(USHORT)>
+*/
+
+{
+ for ( USHORT nPos = 0; nPos < pImp->aItems.Count(); ++nPos )
+ if ( pImp->aItems.GetObject(nPos)->Which() == nSlotId )
+ {
+ // Item entfernen und l"oschen
+ SfxPoolItem *pItem = pImp->aItems.GetObject(nPos);
+ delete pItem;
+ pImp->aItems.Remove(nPos);
+
+ // falls aktiv Bindings benachrichtigen
+ SfxDispatcher *pDispat = GetDispatcher();
+ if ( pDispat )
+ {
+ SfxVoidItem aVoid( nSlotId );
+ pDispat->GetBindings()->Broadcast( SfxPoolItemHint( &aVoid ) );
+ }
+ }
+}
+
+//--------------------------------------------------------------------
+
+void SfxShell::PutItem
+(
+ const SfxPoolItem& rItem /* Instanz, von der eine Kopie erstellt wird,
+ die in der SfxShell in einer Liste
+ gespeichert wird. */
+)
+
+/* [Beschreibung]
+
+ Mit dieser Methode k"onnen beliebige Objekte von Subklassen von
+ <SfxPoolItem> zur Verf"ugung gestellt werden. Diese Austauschtechnik
+ wird ben"otigt, wenn z.B. spezielle <SfxToolBoxControl> Subklassen
+ Zugriff auf bestimmte Daten z.B. der <SfxObjectShell> ben"otigen.
+
+ Falls ein SfxPoolItem mit derselben Slot-Id exisitert, wird dieses
+ automatisch gel"oscht.
+
+
+ [Querverweise]
+
+ <SfxShell::RemoveItem(USHORT)>
+ <SfxShell::GetItem(USHORT)>
+*/
+
+{
+ 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 auf WNT/W95 machte hier Mist, Vorsicht bei Umstellungen
+ const SfxPoolItem *pItem = rItem.Clone();
+ SfxPoolItemHint aItemHint( (SfxPoolItem*) pItem );
+ const USHORT nWhich = rItem.Which();
+ SfxPoolItem **ppLoopItem = (SfxPoolItem**) pImp->aItems.GetData();
+ USHORT nPos;
+ for ( nPos = 0; nPos < pImp->aItems.Count(); ++nPos, ++ppLoopItem )
+ {
+ if ( (*ppLoopItem)->Which() == nWhich )
+ {
+ // Item austauschen
+ delete *ppLoopItem;
+ pImp->aItems.Remove(nPos);
+ pImp->aItems.Insert( (SfxPoolItemPtr) pItem, nPos );
+
+ // falls aktiv Bindings benachrichtigen
+ SfxDispatcher *pDispat = GetDispatcher();
+ if ( pDispat )
+ {
+ SfxBindings* pBindings = pDispat->GetBindings();
+ pBindings->Broadcast( aItemHint );
+ USHORT nSlotId = nWhich; //pItem->GetSlotId();
+ SfxStateCache* pCache = pBindings->GetStateCache( nSlotId );
+ if ( pCache )
+ {
+ pCache->SetState( SFX_ITEM_AVAILABLE, pItem->Clone(), TRUE );
+ pCache->SetCachedState( TRUE );
+ }
+ }
+ return;
+ }
+ }
+
+ Broadcast( aItemHint );
+ pImp->aItems.Insert((SfxPoolItemPtr)pItem, nPos );
+}
+
+//--------------------------------------------------------------------
+
+SfxInterface* SfxShell::GetInterface() const
+
+/* [Beschreibung]
+
+ Mit dieser virtuellen Methode, die durch das Makro <SFX_DECL_INTERFACE>
+ von jeder Subclass mit eigenen Slots automatisch "uberladen wird, kann
+ auf die zu der Subklasse geh"orende <SfxInterface>-Instanz zugegriffen
+ werden.
+
+ Die Klasse SfxShell selbst hat noch kein eigenes SfxInterface
+ (keine Slots), daher wird ein 0-Pointer zur"uckgeliefert.
+*/
+
+{
+ return GetStaticInterface();
+}
+
+//--------------------------------------------------------------------
+
+SfxBroadcaster* SfxShell::GetBroadcaster()
+
+/* [Beschreibung]
+
+ Liefert einen SfxBroadcaster f"ur diese SfxShell-Instanz bis die
+ Klasse SfxShell von SfxBroadcaster abgeleitet ist.
+*/
+
+{
+ return pImp;
+}
+
+//--------------------------------------------------------------------
+
+SfxUndoManager* SfxShell::GetUndoManager()
+
+/* [Beschreibung]
+
+ Jede Subclass von SfxShell kann "uber einen <SfxUndoManager> verf"ugen.
+ Dieser kann in den abgeleiteten Klasse mit <SfxShell:SetUndoManager()>
+ gesetzt werden.
+
+ Die Klasse SfxShell selbst hat noch keinen SfxUndoManager, es wird
+ daher ein 0-Pointer zur"uckgeliefert.
+*/
+
+{
+ return pUndoMgr;
+}
+
+//--------------------------------------------------------------------
+
+void SfxShell::SetUndoManager( SfxUndoManager *pNewUndoMgr )
+
+/* [Beschreibung]
+
+ Setzt einen <SfxUndoManager> f"ur diese <SfxShell> Instanz. F"ur das
+ Undo wird immer nur der Undo-Manager an der jeweils oben auf dem
+ Stack des <SfxDispatcher> liegenden SfxShell verwendet.
+
+ Am "ubergebenen <SfxUndoManager> wird automatisch die aktuelle
+ Max-Undo-Action-Count Einstellung aus den Optionen gesetzt.
+
+ 'pNewUndoMgr' mu\s bis zum Dtor dieser SfxShell-Instanz oder bis
+ zum n"achsten 'SetUndoManager()' existieren.
+*/
+
+{
+ pUndoMgr = pNewUndoMgr;
+ if ( pUndoMgr )
+ pUndoMgr->SetMaxUndoActionCount( (USHORT) SvtUndoOptions().GetUndoCount() );
+}
+
+//--------------------------------------------------------------------
+
+SfxRepeatTarget* SfxShell::GetRepeatTarget() const
+
+/* [Beschreibung]
+
+ Liefert einen Pointer auf die <SfxRepeatTarget>-Instanz, die
+ als RepeatTarget bei SID_REPEAT verwendet wird, wenn der
+ von dieser SfxShell gelieferte <SfxUndoManager> angesprochen wird.
+ Der R"uckgabewert kann 0 sein.
+
+
+ [Anmerkung]
+
+ Eine Ableitung von <SfxShell> oder einer ihrer Subklassen von
+ <SfxRepeatTarget> ist nicht zu empfehlen, da Compiler-Fehler
+ provoziert werden (wegen Call-to-Pointer-to-Member-Function to
+ subclass).
+*/
+
+{
+ return pImp->pRepeatTarget;
+}
+
+//--------------------------------------------------------------------
+
+void SfxShell::SetRepeatTarget( SfxRepeatTarget *pTarget )
+
+/* [Beschreibung]
+
+ Setzt den die <SfxRepeatTarget>-Instanz, die bei SID_REPEAT als
+ RepeatTarget verwendet wird, wenn der von dieser SfxShell gelieferte
+ <SfxUndoManager> angesprochen wird. Durch 'pTarget==0' wird SID_REPEAT
+ f"ur diese SfxShell disabled. Die Instanz '*pTarget' mu\s so lange
+ leben, wie sie angemeldet ist.
+
+
+ [Anmerkung]
+
+ Eine Ableitung von <SfxShell> oder einer ihrer Subklassen von
+ <SfxRepeatTarget> ist nicht zu empfehlen, da Compiler-Fehler
+ provoziert werden (wegen Call-to-Pointer-to-Member-Function to
+ subclass).
+*/
+
+{
+ pImp->pRepeatTarget = pTarget;
+}
+
+//--------------------------------------------------------------------
+
+void SfxShell::Invalidate
+(
+ USHORT nId /* Zu invalidierende Slot-Id oder Which-Id.
+ Falls diese 0 ist (default), werden
+ alle z.Zt. von dieser Shell bedienten
+ Slot-Ids invalidiert. */
+)
+
+/* [Beschreibung]
+
+ Mit dieser Methode k"onnen Slots der Subclasses "uber die Slot-Id
+ oder alternativ "uber die Which-Id invalidiert werden. Slot-Ids,
+ die von der Subclass ererbt sind, werden ebenfalls invalidert.
+
+ [Querverweise]
+ <SfxBindings::Invalidate(USHORT)>
+ <SfxBindings::InvalidateAll(BOOL)>
+*/
+
+{
+ if ( !GetViewShell() )
+ {
+ DBG_ERROR( "wrong Invalidate method called!" );
+ return;
+ }
+
+ Invalidate_Impl( GetViewShell()->GetViewFrame()->GetBindings(), nId );
+}
+
+void SfxShell::Invalidate_Impl( SfxBindings& rBindings, USHORT nId )
+{
+ if ( nId == 0 )
+ {
+ rBindings.InvalidateShell( *this, FALSE );
+ }
+ else
+ {
+ const SfxInterface *pIF = GetInterface();
+ do
+ {
+ const SfxSlot *pSlot = pIF->GetSlot(nId);
+ if ( pSlot )
+ {
+ // bei Enum-Slots ist der Master-Slot zu invalidieren
+ if ( SFX_KIND_ENUM == pSlot->GetKind() )
+ pSlot = pSlot->GetLinkedSlot();
+
+ // den Slot selbst und ggf. auch alle Slave-Slots invalidieren
+ 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, BOOL bMDI )
+
+/* [Beschreibung]
+
+ Diese Methode steuert die Aktivierung der SfxShell-Instanz. Zun"achst
+ wird durch Aufruf der virtuellen Methode <SfxShell::Activate(BOOL)>
+ der Subclass die M"oglichkeit gegeben, auf das Event zu reagieren.
+
+ Bei bMDI == TRUE wird das zugeh"orige SbxObject 'scharfgeschaltet',
+ so da\s Methoden des Objekts unqualifiziert (ohne den Namen des Objekts)
+ vom BASIC gefunden werden.
+*/
+
+{
+#ifdef DBG_UTIL
+ const SfxInterface *p_IF = GetInterface();
+ if ( !p_IF )
+ return;
+#endif
+#ifdef DBG_UTIL_VB
+ String aMsg("SfxShell::DoActivate() ");
+ aMsg += (long)this;
+ aMsg += " ";
+ aMsg += GetInterface()->GetName();
+ aMsg += " bMDI ";
+ if ( bMDI ) aMsg += "MDI";
+ DbgTrace( aMsg.GetBuffer() );
+#endif
+
+ if ( bMDI )
+ {
+ // Frame merken, in dem aktiviert wird
+ pImp->pFrame = pFrame;
+ pImp->bActive = TRUE;
+ }
+
+ // Subklasse benachrichtigen
+ Activate(bMDI);
+}
+
+//--------------------------------------------------------------------
+
+void SfxShell::DoDeactivate_Impl( SfxViewFrame *pFrame, BOOL bMDI )
+
+/* [Beschreibung]
+
+ Diese Methode steuert die Deaktivierung der SfxShell-Instanz. Bei
+ bMDI == TRUE wird zun"achst das SbxObject in einen Status versetzt,
+ so da\s Methoden vom BASIC aus nur noch qualifiziert gerufen werden
+ k"onnen.
+
+ Dann erh"alt in jedem Fall die Subclass durch Aufruf der virtuellen
+ Methode <SfxShell::Deactivate(BOOL)> die M"oglichkeit auf das Event
+ zu reagieren.
+*/
+
+{
+#ifdef DBG_UTIL
+ const SfxInterface *p_IF = GetInterface();
+ if ( !p_IF )
+ return;
+#endif
+#ifdef DBG_UTIL_VB
+ String aMsg("SfxShell::DoDeactivate()");
+ aMsg += (long)this;
+ aMsg += " ";
+ aMsg += GetInterface()->GetName();
+ aMsg += " bMDI ";
+ if ( bMDI ) aMsg += "MDI";
+ DbgTrace( aMsg.GetBuffer() );
+#endif
+
+ // nur wenn er vom Frame kommt (nicht z.B. pop der BASIC-IDE vom AppDisp)
+ if ( bMDI && pImp->pFrame == pFrame )
+ {
+ // austragen
+ pImp->pFrame = 0;
+ pImp->bActive = FALSE;
+ }
+
+ // Subklasse benachrichtigen
+ Deactivate(bMDI);
+}
+
+//--------------------------------------------------------------------
+
+BOOL SfxShell::IsActive() const
+{
+ return pImp->bActive;
+}
+
+//--------------------------------------------------------------------
+
+void SfxShell::Activate
+(
+ BOOL /*bMDI*/ /* TRUE
+ der <SfxDispatcher>, auf dem die SfxShell sich
+ befindet, ist aktiv geworden oder die SfxShell
+ Instanz wurde auf einen aktiven SfxDispatcher
+ gepusht. (vergl. SystemWindow::IsMDIActivate())
+
+ FALSE
+ das zum <SfxViewFrame>, auf dessen SfxDispatcher
+ sich die SfxShell Instanz befindet, wurde
+ aktiviert.
+ (z.B. durch einen geschlossenen Dialog) */
+)
+
+/* [Beschreibung]
+
+ Virtuelle Methode, die beim Aktivieren der SfxShell Instanz gerufen
+ wird, um den Subclasses die Gelegenheit zu geben, auf das Aktivieren
+ zu reagieren.
+
+ Die Basisimplementation ist leer und braucht nicht gerufen zu werden.
+
+
+ [Querverweise]
+ StarView SystemWindow::Activate(BOOL)
+*/
+
+{
+}
+
+//--------------------------------------------------------------------
+
+void SfxShell::Deactivate
+(
+ BOOL /*bMDI*/ /* TRUE
+ der <SfxDispatcher>, auf dem die SfxShell sich
+ befindet, ist inaktiv geworden oder die SfxShell
+ Instanz wurde auf einen aktiven SfxDispatcher
+ gepoppt. (vergl. SystemWindow::IsMDIActivate())
+
+ FALSE
+ das zum <SfxViewFrame>, auf dessen SfxDispatcher
+ sich die SfxShell Instanz befindet, wurde
+ deaktiviert. (z.B. durch einen Dialog) */
+
+)
+
+/* [Beschreibung]
+
+ Virtuelle Methode, die beim Deaktivieren der SfxShell Instanz gerufen
+ wird, um den Subclasses die Gelegenheit zu geben, auf das Deaktivieren
+ zu reagieren.
+
+ Die Basisimplementation ist leer und braucht nicht gerufen zu werden.
+
+
+ [Querverweise]
+ StarView SystemWindow::Dectivate(BOOL)
+*/
+
+{
+}
+
+void SfxShell::ParentActivate
+(
+)
+
+/* [Beschreibung]
+
+ Ein Parent des <SfxDispatcher>, auf dem die SfxShell sich befindet,
+ ist aktiv geworden, oder die SfxShell Instanz wurde auf einen
+ <SfxDispatcher> gepusht, dessen parent aktiv ist.
+
+ Die Basisimplementation ist leer und braucht nicht gerufen zu werden.
+
+ [Querverweise]
+ SfxShell::Activate()
+*/
+{
+}
+
+//--------------------------------------------------------------------
+
+void SfxShell::ParentDeactivate
+(
+)
+
+/* [Beschreibung]
+
+ Der aktive Parent des <SfxDispatcher>, auf dem die SfxShell sich befindet,
+ ist deaktiviert worden.
+
+ Die Basisimplementation ist leer und braucht nicht gerufen zu werden.
+
+ [Querverweise]
+ SfxShell::Deactivate()
+*/
+{
+}
+
+//--------------------------------------------------------------------
+
+ResMgr* SfxShell::GetResMgr() const
+
+/* [Beschreibung]
+
+ Diese Methode liefert den ResMgr der <Resource-DLL>, die von der
+ SfxShell-Instanz verwendet wird. Ist dies ein 0-Pointer, so
+ ist der aktuelle Resource-Manager zu verwenden.
+*/
+
+{
+ return GetInterface()->GetResMgr();
+}
+
+//--------------------------------------------------------------------
+
+FASTBOOL SfxShell::CanExecuteSlot_Impl( const SfxSlot &rSlot )
+
+/* [Beschreibung]
+
+ Diese Methode stellt durch Aufruf der Statusfunktion fest,
+ ob 'rSlot' aktuell ausgef"uhrt werden kann.
+*/
+{
+ // Slot-Status holen
+ SfxItemPool &rPool = GetPool();
+ const USHORT 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;
+}
+
+/* [Beschreibung]
+ Asynchrones ExecuteSlot fuer das RELOAD
+ */
+
+//--------------------------------------------------------------------
+const SfxPoolItem* SfxShell::ExecuteSlot( SfxRequest& rReq, 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, // der weiterzuleitende <SfxRequest>
+ const SfxInterface* pIF // default = 0 bedeutet virtuell besorgen
+)
+
+/* [Beschreibung]
+
+ Diese Methode erm"oglicht das Weiterleiten eines <SfxRequest> an
+ die angegebene Basis-<SfxShell>.
+
+
+ [Beispiel]
+
+ In einer von SfxViewShell abgeleiteten Klasse soll SID_PRINTDOCDIRECT
+ abgefangen werden. Unter bestimmten Umst"anden soll vor dem Drucken
+ eine Abfrage erscheinen, und der Request soll ggf. abgebrochen werden.
+
+ Dazu ist in der IDL dieser Subklasse der o.g. Slot einzutragen. Die
+ Execute-Methode enth"alt dann skizziert:
+
+ void SubViewShell::Exec( SfxRequest &rReq )
+ {
+ if ( rReq.GetSlot() == SID_PRINTDOCDIRECT )
+ {
+ 'dialog'
+ if ( 'condition' )
+ ExecuteSlot( rReq, SfxViewShell::GetInterface() );
+ }
+ }
+
+ Es braucht i.d.R. kein rReq.Done() gerufen zu werden, da das bereits
+ die Implementierung der SfxViewShell erledigt bzw. abgebrochen wurde.
+
+
+ [Querverweise]
+
+ <SfxShell::GetSlotState(USHORT,const SfxInterface*,SfxItemSet*)>
+*/
+
+{
+ if ( !pIF )
+ pIF = GetInterface();
+
+ USHORT 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);
+ if ( !pSlot && SfxMacroConfig::IsMacroSlot( nSlot ) )
+ {
+ SfxMacroInfo* pInfo = SFX_APP()->GetMacroConfig()->GetMacroInfo(nSlot);
+ if ( pInfo )
+ pSlot = pInfo->GetSlot();
+ }
+
+ DBG_ASSERT( pSlot, "slot not supported" );
+
+ SfxExecFunc pFunc = pSlot->GetExecFnc();
+ if ( pFunc )
+ CallExec( pFunc, rReq );
+
+ return rReq.GetReturnValue();
+}
+
+//--------------------------------------------------------------------
+
+const SfxPoolItem* SfxShell::GetSlotState
+(
+ USHORT nSlotId, // Slot-Id des zu befragenden Slots
+ const SfxInterface* pIF, // default = 0 bedeutet virtuell besorgen
+ SfxItemSet* pStateSet // SfxItemSet der Slot-State-Methode
+)
+
+/* [Beschreibung]
+
+ Diese Methode liefert den Status des Slots mit der angegebenen Slot-Id
+ "uber das angegebene Interface.
+
+ Ist der Slot disabled oder in dieser SfxShell (und deren Parent-Shells)
+ nicht bekannt, wird ein 0-Pointer zur"uckgeliefert.
+
+ Hat der Slot keinen Status, wird ein SfxVoidItem zur"uckgeliefert.
+
+ Der Status wird bei pStateSet != 0 gleich in diesem Set gesetzt, so
+ da\s <SfxShell>-Subklassen Slots-"uberladen und auch bei der
+ Status-Methode die Basis-Implementierung rufen k"onnen.
+
+
+ [Beispiel]
+
+ In einer von SfxViewShell abgeleiteten Klasse soll SID_PRINTDOCDIRECT
+ abgefangen werden. Unter bestimmten Umst"anden soll vor dem Drucken
+ eine Abfrage erscheinen, und der Request soll ggf. abgebrochen werden.
+
+ Dazu ist in der IDL dieser Subklasse der o.g. Slot einzutragen. Die
+ Status-Methode enth"alt dann skizziert:
+
+ void SubViewShell::PrintState( SfxItemSet &rState )
+ {
+ if ( rState.GetItemState( SID_PRINTDOCDIRECT ) != SFX_ITEM_UNKNOWN )
+ GetSlotState( SID_PRINTDOCDIRECT, SfxViewShell::GetInterface(),
+ &rState );
+ ...
+ }
+
+
+ [Querverweise]
+
+ <SfxShell::ExecuteSlot(SfxRequest&)>
+*/
+
+{
+ // Slot am angegebenen Interface besorgen
+ 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 && SfxMacroConfig::IsMacroSlot( nSlotId ) )
+ {
+ SfxMacroInfo* pInfo = SFX_APP()->GetMacroConfig()->GetMacroInfo(nSlotId);
+ if ( pInfo )
+ pSlot = pInfo->GetSlot();
+ }
+
+ if ( pSlot )
+ // ggf. auf Which-Id mappen
+ nSlotId = pSlot->GetWhich( rPool );
+
+ // Item und Item-Status besorgen
+ const SfxPoolItem *pItem = NULL;
+ SfxItemSet aSet( rPool, nSlotId, nSlotId ); // pItem stirbt sonst zu fr"uh
+ if ( pSlot )
+ {
+ // Status-Methode rufen
+ SfxStateFunc pFunc = pSlot->GetStateFnc();
+ if ( pFunc )
+ CallState( pFunc, aSet );
+ eState = aSet.GetItemState( nSlotId, TRUE, &pItem );
+
+ // ggf. Default-Item besorgen
+ if ( eState == SFX_ITEM_DEFAULT )
+ {
+ if ( SfxItemPool::IsWhich(nSlotId) )
+ pItem = &rPool.GetDefaultItem(nSlotId);
+ else
+ eState = SFX_ITEM_DONTCARE;
+ }
+ }
+ else
+ eState = SFX_ITEM_UNKNOWN;
+
+ // Item und Item-Status auswerten und ggf. in pStateSet mitpflegen
+ 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, "SetVerbs nur an der ViewShell aufrufen!");
+ if ( !pViewSh )
+ return;
+
+ // Zun"achst alle Statecaches dirty machen, damit keiner mehr versucht,
+ // die Slots zu benutzen
+ {
+ SfxBindings *pBindings =
+ pViewSh->GetViewFrame()->GetDispatcher()->GetBindings();
+ USHORT nCount = pImp->aSlotArr.Count();
+ for (USHORT n1=0; n1<nCount ; n1++)
+ {
+ USHORT nId = SID_VERB_START + n1;
+ pBindings->Invalidate(nId, FALSE, TRUE);
+ }
+ }
+
+ USHORT nr=0;
+ for (sal_Int32 n=0; n<aVerbs.getLength(); n++)
+ {
+ USHORT nSlotId = SID_VERB_START + nr++;
+ DBG_ASSERT(nSlotId <= SID_VERB_END, "Zuviele Verben!");
+ if (nSlotId > SID_VERB_END)
+ break;
+
+ SfxSlot *pNewSlot = new SfxSlot;
+ pNewSlot->nSlotId = nSlotId;
+ pNewSlot->nGroupId = 0;
+
+ // Verb-Slots m"ussen asynchron ausgef"uhrt werden, da sie w"ahrend
+ // des Ausf"uhrens zerst"ort werden k"onnten
+ 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);
+ 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, (USHORT) n);
+ }
+
+ pImp->aVerbList = aVerbs;
+
+ if (pViewSh)
+ {
+ // Der Status von SID_OBJECT wird im Controller direkt an der Shell
+ // abgeholt, es reicht also, ein neues StatusUpdate anzuregen
+ SfxBindings *pBindings = pViewSh->GetViewFrame()->GetDispatcher()->
+ GetBindings();
+ pBindings->Invalidate( SID_OBJECT, TRUE, TRUE );
+ }
+}
+
+//--------------------------------------------------------------------
+
+const com::sun::star::uno::Sequence < com::sun::star::embed::VerbDescriptor >& SfxShell::GetVerbs() const
+{
+ return pImp->aVerbList;
+}
+
+//--------------------------------------------------------------------
+
+void SfxShell::VerbExec(SfxRequest& rReq)
+{
+ USHORT nId = rReq.GetSlot();
+ SfxViewShell *pViewShell = GetViewShell();
+ if ( pViewShell )
+ {
+ 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; n<aList.getLength(); n++)
+ {
+ // check for ReadOnly verbs
+ if ( bReadOnly && !(aList[n].VerbAttributes & embed::VerbAttributes::MS_VERBATTR_NEVERDIRTIES) )
+ continue;
+
+ // check for verbs that shouldn't appear in the menu
+ if ( !(aList[n].VerbAttributes & embed::VerbAttributes::MS_VERBATTR_ONCONTAINERMENU) )
+ continue;
+
+ if (nId == SID_VERB_START + nVerb++)
+ {
+ pViewShell->DoVerb(aList[n].VerbID);
+ rReq.Done();
+ return;
+ }
+ }
+ }
+}
+
+//--------------------------------------------------------------------
+
+void SfxShell::VerbState(SfxItemSet& )
+{
+}
+
+//--------------------------------------------------------------------
+
+const SfxSlot* SfxShell::GetVerbSlot_Impl(USHORT 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,"Falsche VerbId!");
+ USHORT nIndex = nId - SID_VERB_START;
+ DBG_ASSERT(nIndex < rList.getLength(),"Falsche VerbId!");
+
+ if (nIndex < rList.getLength())
+ return pImp->aSlotArr[nIndex];
+ else
+ return 0;
+}
+
+//--------------------------------------------------------------------
+
+void SfxShell::SetHelpId(ULONG nId)
+{
+ pImp->nHelpId = nId;
+}
+
+//--------------------------------------------------------------------
+
+ULONG 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( TRUE );
+ ((SfxDispatcher*) pArg)->GetBindings()->InvalidateAll(FALSE);
+ return 0;
+}
+
+void SfxShell::UIFeatureChanged()
+{
+ SfxViewFrame *pFrame = GetFrame();
+ if ( pFrame && pFrame->IsVisible() )
+ {
+ // Auch dann Update erzwingen, wenn Dispatcher schon geupdated ist,
+ // sonst bleibt evtl. irgendwas in den gebunkerten Tools stecken.
+ // Asynchron aufrufen, um Rekursionen zu vermeiden
+ if ( !pImp->pUpdater )
+ pImp->pUpdater = new svtools::AsynchronLink( Link( this, DispatcherUpdate_Impl ) );
+
+ // Mehrfachaufrufe gestattet
+ pImp->pUpdater->Call( pFrame->GetDispatcher(), TRUE );
+ }
+}
+
+void SfxShell::SetDisableFlags( ULONG nFlags )
+{
+ pImp->nDisableFlags = nFlags;
+}
+
+ULONG SfxShell::GetDisableFlags() const
+{
+ return pImp->nDisableFlags;
+}
+
+SfxItemSet* SfxShell::CreateItemSet( USHORT )
+{
+ return NULL;
+}
+
+void SfxShell::ApplyItemSet( USHORT, const SfxItemSet& )
+{
+}
+
+void SfxShell::SetViewShell_Impl( SfxViewShell* pView )
+{
+ pImp->pViewSh = pView;
+}
+
+
+