xref: /trunk/main/sfx2/source/control/shell.cxx (revision 24c56ab9)
1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_sfx2.hxx"
26 #include <com/sun/star/embed/VerbDescriptor.hpp>
27 #include <com/sun/star/embed/VerbAttributes.hpp>
28 #include <basic/sbstar.hxx>
29 #include <svl/itempool.hxx>
30 #include <svl/undo.hxx>
31 #include <svtools/itemdel.hxx>
32 #include <svtools/asynclink.hxx>
33 #include <basic/sbx.hxx>
34 
35 #include <unotools/undoopt.hxx>
36 
37 #ifndef GCC
38 #endif
39 
40 #include <sfx2/app.hxx>
41 #include <sfx2/shell.hxx>
42 #include <sfx2/bindings.hxx>
43 #include <sfx2/dispatch.hxx>
44 #include <sfx2/viewfrm.hxx>
45 #include <sfx2/objface.hxx>
46 #include <sfx2/objsh.hxx>
47 #include <sfx2/viewsh.hxx>
48 #include <sfx2/dispatch.hxx>
49 #include "sfxtypes.hxx"
50 #include <sfx2/request.hxx>
51 #include <sfx2/mnumgr.hxx>
52 #include "statcach.hxx"
53 #include <sfx2/msgpool.hxx>
54 #include <sfx2/sidebar/ContextChangeBroadcaster.hxx>
55 
56 //====================================================================
57 
58 DBG_NAME(SfxShell)
59 
60 //====================================================================
61 
62 TYPEINIT0(SfxShell);
63 
64 //====================================================================
65 typedef SfxSlot* SfxSlotPtr;
66 SV_DECL_PTRARR_DEL( SfxVerbSlotArr_Impl, SfxSlotPtr, 4, 4)
67 SV_IMPL_PTRARR( SfxVerbSlotArr_Impl, SfxSlotPtr);
68 
69 using namespace com::sun::star;
70 
71 //=========================================================================
72 // SfxShell_Impl
73 //=========================================================================
74 struct SfxShell_Impl: public SfxBroadcaster
75 {
76 	String                      aObjectName;// Name des Sbx-Objects
77 	SfxItemArray_Impl           aItems;     // Datenaustausch auf Item-Basis
78     SfxViewShell*               pViewSh;    // SfxViewShell falls Shell ViewFrame/ViewShell/SubShell ist
79 	SfxViewFrame*               pFrame;     // Frame, falls <UI-aktiv>
80 	SfxRepeatTarget*            pRepeatTarget;
81 //    SbxObjectRef                xParent;
82 	sal_Bool						bInAppBASIC;
83 	sal_Bool                        bActive;
84 	sal_uIntPtr						nDisableFlags;
85 	sal_uIntPtr                       nHelpId;
86     svtools::AsynchronLink*     pExecuter;
87     svtools::AsynchronLink*     pUpdater;
88     SfxVerbSlotArr_Impl         aSlotArr;
89     com::sun::star::uno::Sequence < com::sun::star::embed::VerbDescriptor > aVerbList;
90     ::sfx2::sidebar::ContextChangeBroadcaster maContextChangeBroadcaster;
91 
SfxShell_ImplSfxShell_Impl92 	SfxShell_Impl()  : pExecuter( 0 ), pUpdater( 0 ) {}
~SfxShell_ImplSfxShell_Impl93 	~SfxShell_Impl() { delete pExecuter; delete pUpdater;}
94 };
95 
96 //====================================================================
97 #ifdef DBG_UTIL
98 
SfxShellIdent_Impl(const SfxShell * pSh)99 String SfxShellIdent_Impl( const SfxShell *pSh )
100 
101 /*  [Beschreibung]
102 
103 	Interne Hilfesfunktion. Liefert einen die SfxShell 'pSh' beschreibenden
104 	String zur"uck. Z.B.: SfxApplication[StarWriter]
105 */
106 
107 {
108 	String aIdent( pSh->ISA(SfxApplication) ? DEFINE_CONST_UNICODE("SfxApplication") :
109 				   pSh->ISA(SfxViewFrame) ? DEFINE_CONST_UNICODE("SfxViewFrame") :
110 				   pSh->ISA(SfxViewShell) ? DEFINE_CONST_UNICODE("SfxViewShell") :
111 				   pSh->ISA(SfxObjectShell) ? DEFINE_CONST_UNICODE("SfxObjectShell") : DEFINE_CONST_UNICODE("SfxShell") );
112 	aIdent += '[';
113 	aIdent += pSh->GetName();
114 	aIdent += ']';
115 	return aIdent;
116 }
117 
118 #endif
119 //====================================================================
120 
121 //=========================================================================
122 // SfxShell
123 //=========================================================================
124 
EmptyExecStub(SfxShell *,SfxRequest &)125 void __EXPORT SfxShell::EmptyExecStub(SfxShell *, SfxRequest &)
126 {
127 }
128 
EmptyStateStub(SfxShell *,SfxItemSet &)129 void __EXPORT SfxShell::EmptyStateStub(SfxShell *, SfxItemSet &)
130 {
131 }
132 
SfxShell()133 SfxShell::SfxShell()
134 
135 /*  [Beschreibung]
136 
137 	Der Konstruktor der Klasse SfxShell initialisierung nur einfache
138 	Typen, das dazugeh"orige SbxObject wird erst on-demand erzeugt.
139 	Daher ist das Anlegen einer SfxShell Instanz sehr billig.
140 */
141 
142 :	pImp(0),
143     pPool(0),
144 	pUndoMgr(0)
145 {
146 	DBG_CTOR(SfxShell, 0);
147 	pImp = new SfxShell_Impl;
148 	pImp->pViewSh = 0;
149 	pImp->pFrame = 0;
150 	pImp->pRepeatTarget = 0;
151 	pImp->bInAppBASIC = sal_False;
152 	pImp->nHelpId = 0L;
153 	pImp->bActive = sal_False;
154 	pImp->nDisableFlags = 0;
155 }
156 
157 //-------------------------------------------------------------------------
158 
SfxShell(SfxViewShell * pViewSh)159 SfxShell::SfxShell( SfxViewShell *pViewSh )
160 
161 /*  [Beschreibung]
162 
163 	Der Konstruktor der Klasse SfxShell initialisierung nur einfache
164 	Typen, das dazugeh"orige SbxObject wird erst on-demand erzeugt.
165 	Daher ist das Anlegen einer SfxShell Instanz sehr billig.
166 */
167 
168 :	pImp(0),
169     pPool(0),
170 	pUndoMgr(0)
171 {
172 	DBG_CTOR(SfxShell, 0);
173 	pImp = new SfxShell_Impl;
174 	pImp->pViewSh = pViewSh;
175 	pImp->pFrame = 0;
176 	pImp->pRepeatTarget = 0;
177 	pImp->bInAppBASIC = sal_False;
178 	pImp->nHelpId = 0L;
179 	pImp->bActive = sal_False;
180 }
181 
182 //--------------------------------------------------------------------
183 
~SfxShell()184 SfxShell::~SfxShell()
185 
186 /*  [Beschreibung]
187 
188 	Die Verbindungs zu einem ggf. zugeh"origen SbxObject wird gel"ost.
189 	Das SbxObject existiert ggf. weiter, kann aber keine Funktionen
190 	mehr ausf"uhren und keine Properties mehr bereitstellen.
191 */
192 
193 {
194 	DBG_DTOR(SfxShell, 0);
195 
196 
197 	delete pImp;
198 }
199 
200 //--------------------------------------------------------------------
201 
SetName(const String & rName)202 void SfxShell::SetName( const String &rName )
203 
204 /*  [Beschreibung]
205 
206 	Setzt den Namen des Shell-Objekts. Mit diesem Namen kann die
207 	SfxShell-Instanz vom BASIC aus angesprochen werden.
208 */
209 
210 {
211 	pImp->aObjectName = rName;
212 }
213 
214 //--------------------------------------------------------------------
215 
GetName() const216 const String& SfxShell::GetName() const
217 
218 /*  [Beschreibung]
219 
220 	Liefert den Namen des Shell-Objekts. Mit diesem Namen kann die
221 	SfxShell-Instanz vom BASIC aus angesprochen werden.
222 */
223 
224 {
225 	return pImp->aObjectName;
226 }
227 
228 //--------------------------------------------------------------------
229 
GetGlobalName() const230 SvGlobalName SfxShell::GetGlobalName() const
231 
232 /*  [Beschreibung]
233 
234 	Liefert den Global Unique Identifier des Shell-Objekts. Mit diesem
235 	Namen kann die SfxShell-Instanz z.B. via OLE Automation angesprochen
236 	werden, bzw. in der Registration-Database gefunden werden.
237 */
238 
239 {
240 	return SvGlobalName();
241 }
242 
243 //--------------------------------------------------------------------
244 
GetDispatcher() const245 SfxDispatcher* SfxShell::GetDispatcher() const
246 
247 /*  [Beschreibung]
248 
249 	Diese Methode liefert einen Pointer auf den <SfxDispatcher>, in
250 	dem die SfxShell gerade <UI-aktiv> ist bzw. einen 0-Pointer, wenn
251 	sie gerade nicht UI-aktiv ist.
252 
253 	Der zur"uckgegebene Pointer ist nur im unmittelbaren Kontext des
254 	Methodenaufrufs g"ultig.
255 */
256 
257 {
258 	return pImp->pFrame ? pImp->pFrame->GetDispatcher() : 0;
259 }
260 
261 //--------------------------------------------------------------------
262 
GetViewShell() const263 SfxViewShell* SfxShell::GetViewShell() const
264 
265 /*  [Beschreibung]
266 
267 	Liefert bei SubShells die SfxViewShell, in der sie liegen. Sonst und
268 	falls nicht vom App-Entwickler angegeben liefert diese Methode 0.
269 */
270 
271 {
272 	return pImp->pViewSh;
273 }
274 
275 //--------------------------------------------------------------------
276 
GetFrame() const277 SfxViewFrame* SfxShell::GetFrame() const
278 
279 /*  [Beschreibung]
280 
281 	Diese Methode liefert einen Pointer auf den <SfxViewFrame>, dem diese
282 	SfxShell-Instanz zugeordnet ist oder in dem sie zur Zeit <UI-aktiv> ist.
283 	Ein 0-Pointer wird geliefert, wenn diese SfxShell-OInstanz gerade nicht
284 	UI-aktiv ist und auch keinem SfxViewFrame fest zugeordnet ist.
285 
286 	Der zur"uckgegebene Pointer ist nur im unmittelbaren Kontext des
287 	Methodenaufrufs g"ultig.
288 
289 
290 	[Anmerkung]
291 
292 	Nur Instanzen von Subklasse von SfxApplication und SfxObjectShell sollten
293 	hier einen 0-Pointer liefern. Ansonsten liegt ein Fehler im Anwendungs-
294 	programm vor (falscher Ctor von SfxShell gerufen).
295 
296 
297 	[Querverweise]
298 
299 	<SfxViewShell::GetViewFrame()const>
300 */
301 
302 {
303 	if ( pImp->pFrame )
304 		return pImp->pFrame;
305 	if ( pImp->pViewSh )
306 		return pImp->pViewSh->GetViewFrame();
307 	return 0;
308 }
309 
310 //--------------------------------------------------------------------
311 
GetItem(sal_uInt16 nSlotId) const312 const SfxPoolItem* SfxShell::GetItem
313 (
314 	sal_uInt16  nSlotId         // Slot-Id des zu erfragenden <SfxPoolItem>s
315 )   const
316 
317 /*  [Beschreibung]
318 
319 	Mit dieser Methode kann auf beliebige Objekte von Subklassen von
320 	<SfxPoolItem> zugegriffen werden. Diese Austauschtechnik wird ben"otigt,
321 	wenn z.B. spezielle <SfxToolBoxControl> Subklassen Zugriff auf
322 	bestimmte Daten z.B. der <SfxObjectShell> ben"otigen.
323 
324 	Die zur"uckgelieferte Instanz geh"ort der jeweilige SfxShell und
325 	darf nur im unmittelbaren Kontext des Methodenaufrufs verwendet werden.
326 
327 
328 	[Querverweise]
329 
330 	<SfxShell::PutItem(const SfxPoolItem&)>
331 	<SfxShell::RemoveItem(sal_uInt16)>
332 */
333 
334 {
335 	for ( sal_uInt16 nPos = 0; nPos < pImp->aItems.Count(); ++nPos )
336 		if ( pImp->aItems.GetObject(nPos)->Which() == nSlotId )
337 			return pImp->aItems.GetObject(nPos);
338 	return 0;
339 }
340 
341 //--------------------------------------------------------------------
342 
RemoveItem(sal_uInt16 nSlotId)343 void SfxShell::RemoveItem
344 (
345 	sal_uInt16  nSlotId         // Slot-Id des zu l"oschenden <SfxPoolItem>s
346 )
347 
348 /*  [Beschreibung]
349 
350 	Mit dieser Methode k"onnen die allgemein zur Verf"ugung gestellten
351 	Instanzen von Subklassen von <SfxPoolItem> aus der SfxShell entfernt
352 	werden.
353 
354 	Die gespeicherte Instanz wird gel"oscht.
355 
356 
357 	[Querverweise]
358 
359 	<SfxShell::PutItem(const SfxPoolItem&)>
360 	<SfxShell::GetItem(sal_uInt16)>
361 */
362 
363 {
364 	for ( sal_uInt16 nPos = 0; nPos < pImp->aItems.Count(); ++nPos )
365 		if ( pImp->aItems.GetObject(nPos)->Which() == nSlotId )
366 		{
367 			// Item entfernen und l"oschen
368 			SfxPoolItem *pItem = pImp->aItems.GetObject(nPos);
369 			delete pItem;
370 			pImp->aItems.Remove(nPos);
371 
372 			// falls aktiv Bindings benachrichtigen
373 			SfxDispatcher *pDispat = GetDispatcher();
374 			if ( pDispat )
375 			{
376 				SfxVoidItem aVoid( nSlotId );
377 				pDispat->GetBindings()->Broadcast( SfxPoolItemHint( &aVoid ) );
378 			}
379 		}
380 }
381 
382 //--------------------------------------------------------------------
383 
PutItem(const SfxPoolItem & rItem)384 void SfxShell::PutItem
385 (
386 	const SfxPoolItem&  rItem   /*  Instanz, von der eine Kopie erstellt wird,
387 									die in der SfxShell in einer Liste
388 									gespeichert wird. */
389 )
390 
391 /*  [Beschreibung]
392 
393 	Mit dieser Methode k"onnen beliebige Objekte von Subklassen von
394 	<SfxPoolItem> zur Verf"ugung gestellt werden. Diese Austauschtechnik
395 	wird ben"otigt, wenn z.B. spezielle <SfxToolBoxControl> Subklassen
396 	Zugriff auf bestimmte Daten z.B. der <SfxObjectShell> ben"otigen.
397 
398 	Falls ein SfxPoolItem mit derselben Slot-Id exisitert, wird dieses
399 	automatisch gel"oscht.
400 
401 
402 	[Querverweise]
403 
404 	<SfxShell::RemoveItem(sal_uInt16)>
405 	<SfxShell::GetItem(sal_uInt16)>
406 */
407 
408 {
409 	DBG_ASSERT( !rItem.ISA(SfxSetItem), "SetItems aren't allowed here" );
410 	DBG_ASSERT( SfxItemPool::IsSlot( rItem.Which() ),
411 				"items with Which-Ids aren't allowed here" );
412 
413 	// MSC auf WNT/W95 machte hier Mist, Vorsicht bei Umstellungen
414 	const SfxPoolItem *pItem = rItem.Clone();
415 	SfxPoolItemHint aItemHint( (SfxPoolItem*) pItem );
416 	const sal_uInt16 nWhich = rItem.Which();
417 	SfxPoolItem **ppLoopItem = (SfxPoolItem**) pImp->aItems.GetData();
418 	sal_uInt16 nPos;
419 	for ( nPos = 0; nPos < pImp->aItems.Count(); ++nPos, ++ppLoopItem )
420 	{
421 		if ( (*ppLoopItem)->Which() == nWhich )
422 		{
423 			// Item austauschen
424 			delete *ppLoopItem;
425 			pImp->aItems.Remove(nPos);
426 			pImp->aItems.Insert( (SfxPoolItemPtr) pItem, nPos );
427 
428 			// falls aktiv Bindings benachrichtigen
429 			SfxDispatcher *pDispat = GetDispatcher();
430 			if ( pDispat )
431             {
432                 SfxBindings* pBindings = pDispat->GetBindings();
433                 pBindings->Broadcast( aItemHint );
434                 sal_uInt16 nSlotId = nWhich; //pItem->GetSlotId();
435                 SfxStateCache* pCache = pBindings->GetStateCache( nSlotId );
436                 if ( pCache )
437                 {
438                     pCache->SetState( SFX_ITEM_AVAILABLE, pItem->Clone(), sal_True );
439                     pCache->SetCachedState( sal_True );
440                 }
441             }
442             return;
443 		}
444 	}
445 
446 	Broadcast( aItemHint );
447 	pImp->aItems.Insert((SfxPoolItemPtr)pItem, nPos );
448 }
449 
450 //--------------------------------------------------------------------
451 
GetInterface() const452 SfxInterface* SfxShell::GetInterface() const
453 
454 /*  [Beschreibung]
455 
456 	Mit dieser virtuellen Methode, die durch das Makro <SFX_DECL_INTERFACE>
457 	von jeder Subclass mit eigenen Slots automatisch "uberladen wird, kann
458 	auf die zu der Subklasse geh"orende <SfxInterface>-Instanz zugegriffen
459 	werden.
460 
461 	Die Klasse SfxShell selbst hat noch kein eigenes SfxInterface
462 	(keine Slots), daher wird ein 0-Pointer zur"uckgeliefert.
463 */
464 
465 {
466     return GetStaticInterface();
467 }
468 
469 //--------------------------------------------------------------------
470 
GetBroadcaster()471 SfxBroadcaster* SfxShell::GetBroadcaster()
472 
473 /*	[Beschreibung]
474 
475 	Liefert einen SfxBroadcaster f"ur diese SfxShell-Instanz bis die
476 	Klasse SfxShell von SfxBroadcaster abgeleitet ist.
477 */
478 
479 {
480 	return pImp;
481 }
482 
483 //--------------------------------------------------------------------
484 
GetUndoManager()485 ::svl::IUndoManager* SfxShell::GetUndoManager()
486 
487 /*  [Beschreibung]
488 
489 	Jede Subclass von SfxShell kann "uber einen <SfxUndoManager> verf"ugen.
490 	Dieser kann in den abgeleiteten Klasse mit <SfxShell:SetUndoManager()>
491 	gesetzt werden.
492 
493 	Die Klasse SfxShell selbst hat noch keinen SfxUndoManager, es wird
494 	daher ein 0-Pointer zur"uckgeliefert.
495 */
496 
497 {
498 	return pUndoMgr;
499 }
500 
501 //--------------------------------------------------------------------
502 
SetUndoManager(::svl::IUndoManager * pNewUndoMgr)503 void SfxShell::SetUndoManager( ::svl::IUndoManager *pNewUndoMgr )
504 
505 /*  [Beschreibung]
506 
507 	Setzt einen <SfxUndoManager> f"ur diese <SfxShell> Instanz. F"ur das
508 	Undo wird immer nur der Undo-Manager an der jeweils oben auf dem
509 	Stack des <SfxDispatcher> liegenden SfxShell verwendet.
510 
511 	Am "ubergebenen <SfxUndoManager> wird automatisch die aktuelle
512 	Max-Undo-Action-Count Einstellung aus den Optionen gesetzt.
513 
514 	'pNewUndoMgr' mu\s bis zum Dtor dieser SfxShell-Instanz oder bis
515 	zum n"achsten 'SetUndoManager()' existieren.
516 */
517 
518 {
519     OSL_ENSURE( ( pUndoMgr == NULL ) || ( pNewUndoMgr == NULL ) || ( pUndoMgr == pNewUndoMgr ),
520         "SfxShell::SetUndoManager: exchanging one non-NULL manager with another non-NULL manager? Suspicious!" );
521     // there's at least one client of our UndoManager - the DocumentUndoManager at the SfxBaseModel - which
522     // caches the UndoManager, and registers itself as listener. If exchanging non-NULL UndoManagers is really
523     // a supported scenario (/me thinks it is not), then we would need to notify all such clients instances.
524 
525 	pUndoMgr = pNewUndoMgr;
526 	if ( pUndoMgr )
527         pUndoMgr->SetMaxUndoActionCount( (sal_uInt16) SvtUndoOptions().GetUndoCount() );
528 }
529 
530 //--------------------------------------------------------------------
531 
GetRepeatTarget() const532 SfxRepeatTarget* SfxShell::GetRepeatTarget() const
533 
534 /*  [Beschreibung]
535 
536 	Liefert einen Pointer auf die <SfxRepeatTarget>-Instanz, die
537 	als RepeatTarget bei SID_REPEAT verwendet wird, wenn der
538 	von dieser SfxShell gelieferte <SfxUndoManager> angesprochen wird.
539 	Der R"uckgabewert kann 0 sein.
540 
541 
542 	[Anmerkung]
543 
544 	Eine Ableitung von <SfxShell> oder einer ihrer Subklassen von
545 	<SfxRepeatTarget> ist nicht zu empfehlen, da Compiler-Fehler
546 	provoziert werden (wegen Call-to-Pointer-to-Member-Function to
547 	subclass).
548 */
549 
550 {
551 	return pImp->pRepeatTarget;
552 }
553 
554 //--------------------------------------------------------------------
555 
SetRepeatTarget(SfxRepeatTarget * pTarget)556 void SfxShell::SetRepeatTarget( SfxRepeatTarget *pTarget )
557 
558 /*  [Beschreibung]
559 
560 	Setzt den die <SfxRepeatTarget>-Instanz, die bei SID_REPEAT als
561 	RepeatTarget verwendet wird, wenn der von dieser SfxShell gelieferte
562 	<SfxUndoManager> angesprochen wird. Durch 'pTarget==0' wird SID_REPEAT
563 	f"ur diese SfxShell disabled. Die Instanz '*pTarget' mu\s so lange
564 	leben, wie sie angemeldet ist.
565 
566 
567 	[Anmerkung]
568 
569 	Eine Ableitung von <SfxShell> oder einer ihrer Subklassen von
570 	<SfxRepeatTarget> ist nicht zu empfehlen, da Compiler-Fehler
571 	provoziert werden (wegen Call-to-Pointer-to-Member-Function to
572 	subclass).
573 */
574 
575 {
576 	pImp->pRepeatTarget = pTarget;
577 }
578 
579 //--------------------------------------------------------------------
580 
Invalidate(sal_uInt16 nId)581 void SfxShell::Invalidate
582 (
583 	sal_uInt16          nId     /* Zu invalidierende Slot-Id oder Which-Id.
584 							   Falls diese 0 ist (default), werden
585 							   alle z.Zt. von dieser Shell bedienten
586 							   Slot-Ids invalidiert. */
587 )
588 
589 /*  [Beschreibung]
590 
591 	Mit dieser Methode k"onnen Slots der Subclasses "uber die Slot-Id
592 	oder alternativ "uber die Which-Id invalidiert werden. Slot-Ids,
593 	die von der Subclass ererbt sind, werden ebenfalls invalidert.
594 
595 	[Querverweise]
596 	<SfxBindings::Invalidate(sal_uInt16)>
597 	<SfxBindings::InvalidateAll(sal_Bool)>
598 */
599 
600 {
601     if ( !GetViewShell() )
602     {
603         DBG_ERROR( "wrong Invalidate method called!" );
604         return;
605     }
606 
607     Invalidate_Impl( GetViewShell()->GetViewFrame()->GetBindings(), nId );
608 }
609 
Invalidate_Impl(SfxBindings & rBindings,sal_uInt16 nId)610 void SfxShell::Invalidate_Impl( SfxBindings& rBindings, sal_uInt16 nId )
611 {
612 	if ( nId == 0 )
613     {
614         rBindings.InvalidateShell( *this, sal_False );
615     }
616 	else
617 	{
618 		const SfxInterface *pIF = GetInterface();
619 		do
620 		{
621 			const SfxSlot *pSlot = pIF->GetSlot(nId);
622 			if ( pSlot )
623 			{
624 				// bei Enum-Slots ist der Master-Slot zu invalidieren
625 				if ( SFX_KIND_ENUM == pSlot->GetKind() )
626 					pSlot = pSlot->GetLinkedSlot();
627 
628 				// den Slot selbst und ggf. auch alle Slave-Slots invalidieren
629 				rBindings.Invalidate( pSlot->GetSlotId() );
630 				for ( const SfxSlot *pSlave = pSlot->GetLinkedSlot();
631 					  pSlave && pIF->ContainsSlot_Impl( pSlave ) &&
632 						pSlave->GetLinkedSlot() == pSlot;
633 					  ++pSlave )
634 					rBindings.Invalidate( pSlave->GetSlotId() );
635 
636 				return;
637 			}
638 
639 			pIF = pIF->GetGenoType();
640 		}
641 
642 		while ( pIF );
643 
644 		DBG_WARNING( "W3: invalidating slot-id unknown in shell" );
645 	}
646 }
647 
648 //--------------------------------------------------------------------
649 
DoActivate_Impl(SfxViewFrame * pFrame,sal_Bool bMDI)650 void SfxShell::DoActivate_Impl( SfxViewFrame *pFrame, sal_Bool bMDI )
651 
652 /*  [Beschreibung]
653 
654 	Diese Methode steuert die Aktivierung der SfxShell-Instanz. Zun"achst
655 	wird durch Aufruf der virtuellen Methode <SfxShell::Activate(sal_Bool)>
656 	der Subclass die M"oglichkeit gegeben, auf das Event zu reagieren.
657 
658 	Bei bMDI == TRUE wird das zugeh"orige SbxObject 'scharfgeschaltet',
659 	so da\s Methoden des Objekts unqualifiziert (ohne den Namen des Objekts)
660 	vom BASIC gefunden werden.
661 */
662 
663 {
664 #ifdef DBG_UTIL
665 	const SfxInterface *p_IF = GetInterface();
666 	if ( !p_IF )
667 		return;
668 #endif
669 #ifdef DBG_UTIL_VB
670 		String aMsg("SfxShell::DoActivate() ");
671 		aMsg += (long)this;
672 		aMsg += "  ";
673 		aMsg += GetInterface()->GetName();
674 		aMsg += " bMDI ";
675 		if ( bMDI ) aMsg += "MDI";
676 		DbgTrace( aMsg.GetBuffer() );
677 #endif
678 
679 	if ( bMDI )
680 	{
681 		// Frame merken, in dem aktiviert wird
682 		pImp->pFrame = pFrame;
683 		pImp->bActive = sal_True;
684 	}
685 
686 	// Subklasse benachrichtigen
687 	Activate(bMDI);
688 }
689 
690 //--------------------------------------------------------------------
691 
DoDeactivate_Impl(SfxViewFrame * pFrame,sal_Bool bMDI)692 void SfxShell::DoDeactivate_Impl( SfxViewFrame *pFrame, sal_Bool bMDI )
693 
694 /*  [Beschreibung]
695 
696 	Diese Methode steuert die Deaktivierung der SfxShell-Instanz. Bei
697 	bMDI == TRUE wird zun"achst das SbxObject in einen Status versetzt,
698 	so da\s Methoden vom BASIC aus nur noch qualifiziert gerufen werden
699 	k"onnen.
700 
701 	Dann erh"alt in jedem Fall die Subclass durch Aufruf der virtuellen
702 	Methode <SfxShell::Deactivate(sal_Bool)> die M"oglichkeit auf das Event
703 	zu reagieren.
704 */
705 
706 {
707 #ifdef DBG_UTIL
708 	const SfxInterface *p_IF = GetInterface();
709 	if ( !p_IF )
710 		return;
711 #endif
712 #ifdef DBG_UTIL_VB
713 		String aMsg("SfxShell::DoDeactivate()");
714 		aMsg += (long)this;
715 		aMsg += "  ";
716 		aMsg += GetInterface()->GetName();
717 		aMsg += " bMDI ";
718 		if ( bMDI ) aMsg += "MDI";
719 		DbgTrace( aMsg.GetBuffer() );
720 #endif
721 
722 	// nur wenn er vom Frame kommt (nicht z.B. pop der BASIC-IDE vom AppDisp)
723 	if ( bMDI && pImp->pFrame == pFrame )
724 	{
725 		// austragen
726 		pImp->pFrame = 0;
727 		pImp->bActive = sal_False;
728 	}
729 
730 	// Subklasse benachrichtigen
731 	Deactivate(bMDI);
732 }
733 
734 //--------------------------------------------------------------------
735 
IsActive() const736 sal_Bool SfxShell::IsActive() const
737 {
738 	return pImp->bActive;
739 }
740 
741 //--------------------------------------------------------------------
742 
Activate(sal_Bool)743 void SfxShell::Activate
744 (
745 	sal_Bool    /*bMDI*/        /*  TRUE
746 							der <SfxDispatcher>, auf dem die SfxShell sich
747 							befindet, ist aktiv geworden oder die SfxShell
748 							Instanz wurde auf einen aktiven SfxDispatcher
749 							gepusht. (vergl. SystemWindow::IsMDIActivate())
750 
751 							FALSE
752 							das zum <SfxViewFrame>, auf dessen SfxDispatcher
753 							sich die SfxShell Instanz befindet, wurde
754 							aktiviert.
755 							(z.B. durch einen geschlossenen Dialog) */
756 )
757 
758 /*  [Beschreibung]
759 
760 	Virtuelle Methode, die beim Aktivieren der SfxShell Instanz gerufen
761 	wird, um den Subclasses die Gelegenheit zu geben, auf das Aktivieren
762 	zu reagieren.
763 
764 	[Querverweise]
765 	StarView SystemWindow::Activate(sal_Bool)
766 */
767 
768 {
769     BroadcastContextForActivation(true);
770 }
771 
772 //--------------------------------------------------------------------
773 
Deactivate(sal_Bool)774 void SfxShell::Deactivate
775 (
776 	sal_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())
781 
782 							FALSE
783 							das zum <SfxViewFrame>, auf dessen SfxDispatcher
784 							sich die SfxShell Instanz befindet, wurde
785 							deaktiviert. (z.B. durch einen Dialog) */
786 
787 )
788 
789 /*  [Beschreibung]
790 
791 	Virtuelle Methode, die beim Deaktivieren der SfxShell Instanz gerufen
792 	wird, um den Subclasses die Gelegenheit zu geben, auf das Deaktivieren
793 	zu reagieren.
794 
795 	[Querverweise]
796 	StarView SystemWindow::Dectivate(sal_Bool)
797 */
798 
799 {
800     BroadcastContextForActivation(false);
801 }
802 
803 
ParentActivate()804 void SfxShell::ParentActivate
805 (
806 )
807 
808 /*  [Beschreibung]
809 
810 	Ein Parent des <SfxDispatcher>, auf dem die SfxShell sich befindet,
811 	ist aktiv geworden, oder die SfxShell Instanz wurde auf einen
812 	<SfxDispatcher> gepusht, dessen parent aktiv ist.
813 
814 	Die Basisimplementation ist leer und braucht nicht gerufen zu werden.
815 
816 	[Querverweise]
817 	SfxShell::Activate()
818 */
819 {
820 }
821 
822 //--------------------------------------------------------------------
823 
ParentDeactivate()824 void SfxShell::ParentDeactivate
825 (
826 )
827 
828 /*  [Beschreibung]
829 
830 	Der aktive Parent des <SfxDispatcher>, auf dem die SfxShell sich befindet,
831 	ist deaktiviert worden.
832 
833 	Die Basisimplementation ist leer und braucht nicht gerufen zu werden.
834 
835 	[Querverweise]
836 	SfxShell::Deactivate()
837 */
838 {
839 }
840 
841 //--------------------------------------------------------------------
842 
GetResMgr() const843 ResMgr* SfxShell::GetResMgr() const
844 
845 /*  [Beschreibung]
846 
847 	Diese Methode liefert den ResMgr der <Resource-DLL>, die von der
848 	SfxShell-Instanz verwendet wird. Ist dies ein 0-Pointer, so
849 	ist der aktuelle Resource-Manager zu verwenden.
850 */
851 
852 {
853 	return GetInterface()->GetResMgr();
854 }
855 
856 //--------------------------------------------------------------------
857 
CanExecuteSlot_Impl(const SfxSlot & rSlot)858 bool SfxShell::CanExecuteSlot_Impl( const SfxSlot &rSlot )
859 
860 /*  [Beschreibung]
861 
862 	Diese Methode stellt durch Aufruf der Statusfunktion fest,
863 	ob 'rSlot' aktuell ausgef"uhrt werden kann.
864 */
865 {
866 	// Slot-Status holen
867 	SfxItemPool &rPool = GetPool();
868 	const sal_uInt16 nId = rSlot.GetWhich( rPool );
869 	SfxItemSet aSet(rPool, nId, nId);
870 	SfxStateFunc pFunc = rSlot.GetStateFnc();
871 	CallState( pFunc, aSet );
872 	return aSet.GetItemState(nId) != SFX_ITEM_DISABLED;
873 }
874 
875 //--------------------------------------------------------------------
876 
ShellCall_Impl(void * pObj,void * pArg)877 long ShellCall_Impl( void* pObj, void* pArg )
878 {
879 	((SfxShell* )pObj)->ExecuteSlot( *(SfxRequest*)pArg, (SfxInterface*)0L );
880 	return 0;
881 }
882 
883 /*  [Beschreibung]
884 	Asynchrones ExecuteSlot fuer das RELOAD
885  */
886 
887 //--------------------------------------------------------------------
ExecuteSlot(SfxRequest & rReq,sal_Bool bAsync)888 const SfxPoolItem* SfxShell::ExecuteSlot( SfxRequest& rReq, sal_Bool bAsync )
889 {
890 	if( !bAsync )
891 		return ExecuteSlot( rReq, (SfxInterface*)0L );
892 	else
893 	{
894 		if( !pImp->pExecuter )
895             pImp->pExecuter = new svtools::AsynchronLink(
896 				Link( this, ShellCall_Impl ) );
897 		pImp->pExecuter->Call( new SfxRequest( rReq ) );
898 		return 0;
899 	}
900 }
901 
ExecuteSlot(SfxRequest & rReq,const SfxInterface * pIF)902 const SfxPoolItem* SfxShell::ExecuteSlot
903 (
904 	SfxRequest &rReq,			// der weiterzuleitende <SfxRequest>
905 	const SfxInterface* pIF     // default = 0 bedeutet virtuell besorgen
906 )
907 
908 /*  [Beschreibung]
909 
910 	Diese Methode erm"oglicht das Weiterleiten eines <SfxRequest> an
911 	die angegebene Basis-<SfxShell>.
912 
913 
914 	[Beispiel]
915 
916 	In einer von SfxViewShell abgeleiteten Klasse soll SID_PRINTDOCDIRECT
917 	abgefangen werden. Unter bestimmten Umst"anden soll vor dem Drucken
918 	eine Abfrage erscheinen, und der Request soll ggf. abgebrochen werden.
919 
920 	Dazu ist in der IDL dieser Subklasse der o.g. Slot einzutragen. Die
921 	Execute-Methode enth"alt dann skizziert:
922 
923 	void SubViewShell::Exec( SfxRequest &rReq )
924 	{
925 		if ( rReq.GetSlot() == SID_PRINTDOCDIRECT )
926 		{
927 			'dialog'
928 			if ( 'condition' )
929 				ExecuteSlot( rReq, SfxViewShell::GetInterface() );
930 		}
931 	}
932 
933 	Es braucht i.d.R. kein rReq.Done() gerufen zu werden, da das bereits
934 	die Implementierung der SfxViewShell erledigt bzw. abgebrochen wurde.
935 
936 
937 	[Querverweise]
938 
939 	<SfxShell::GetSlotState(sal_uInt16,const SfxInterface*,SfxItemSet*)>
940 */
941 
942 {
943 	if ( !pIF )
944 		pIF = GetInterface();
945 
946     sal_uInt16 nSlot = rReq.GetSlot();
947     const SfxSlot* pSlot = NULL;
948     if ( nSlot >= SID_VERB_START && nSlot <= SID_VERB_END )
949         pSlot = GetVerbSlot_Impl(nSlot);
950     if ( !pSlot )
951         pSlot = pIF->GetSlot(nSlot);
952 	DBG_ASSERT( pSlot, "slot not supported" );
953 
954 	SfxExecFunc pFunc = pSlot->GetExecFnc();
955     if ( pFunc )
956         CallExec( pFunc, rReq );
957 
958 	return rReq.GetReturnValue();
959 }
960 
961 //--------------------------------------------------------------------
962 
GetSlotState(sal_uInt16 nSlotId,const SfxInterface * pIF,SfxItemSet * pStateSet)963 const SfxPoolItem* SfxShell::GetSlotState
964 (
965 	sal_uInt16              nSlotId,    // Slot-Id des zu befragenden Slots
966 	const SfxInterface* pIF,        // default = 0 bedeutet virtuell besorgen
967 	SfxItemSet*         pStateSet   // SfxItemSet der Slot-State-Methode
968 )
969 
970 /*  [Beschreibung]
971 
972 	Diese Methode liefert den Status des Slots mit der angegebenen Slot-Id
973 	"uber das angegebene Interface.
974 
975 	Ist der Slot disabled oder in dieser SfxShell (und deren Parent-Shells)
976 	nicht bekannt, wird ein 0-Pointer zur"uckgeliefert.
977 
978 	Hat der Slot keinen Status, wird ein SfxVoidItem zur"uckgeliefert.
979 
980 	Der Status wird bei pStateSet != 0 gleich in diesem Set gesetzt, so
981 	da\s <SfxShell>-Subklassen Slots-"uberladen und auch bei der
982 	Status-Methode die Basis-Implementierung rufen k"onnen.
983 
984 
985 	[Beispiel]
986 
987 	In einer von SfxViewShell abgeleiteten Klasse soll SID_PRINTDOCDIRECT
988 	abgefangen werden. Unter bestimmten Umst"anden soll vor dem Drucken
989 	eine Abfrage erscheinen, und der Request soll ggf. abgebrochen werden.
990 
991 	Dazu ist in der IDL dieser Subklasse der o.g. Slot einzutragen. Die
992 	Status-Methode enth"alt dann skizziert:
993 
994 	void SubViewShell::PrintState( SfxItemSet &rState )
995 	{
996 		if ( rState.GetItemState( SID_PRINTDOCDIRECT ) != SFX_ITEM_UNKNOWN )
997 			GetSlotState( SID_PRINTDOCDIRECT, SfxViewShell::GetInterface(),
998 					&rState );
999 		...
1000 	}
1001 
1002 
1003 	[Querverweise]
1004 
1005 	<SfxShell::ExecuteSlot(SfxRequest&)>
1006 */
1007 
1008 {
1009 	// Slot am angegebenen Interface besorgen
1010 	if ( !pIF )
1011 		pIF = GetInterface();
1012 	SfxItemState eState;
1013 	SfxItemPool &rPool = GetPool();
1014 
1015     const SfxSlot* pSlot = NULL;
1016     if ( nSlotId >= SID_VERB_START && nSlotId <= SID_VERB_END )
1017         pSlot = GetVerbSlot_Impl(nSlotId);
1018     if ( !pSlot )
1019         pSlot = pIF->GetSlot(nSlotId);
1020 	if ( pSlot )
1021 		// ggf. auf Which-Id mappen
1022 		nSlotId = pSlot->GetWhich( rPool );
1023 
1024 	// Item und Item-Status besorgen
1025 	const SfxPoolItem *pItem = NULL;
1026 	SfxItemSet aSet( rPool, nSlotId, nSlotId ); // pItem stirbt sonst zu fr"uh
1027 	if ( pSlot )
1028 	{
1029 		// Status-Methode rufen
1030 		SfxStateFunc pFunc = pSlot->GetStateFnc();
1031         if ( pFunc )
1032             CallState( pFunc, aSet );
1033 		eState = aSet.GetItemState( nSlotId, sal_True, &pItem );
1034 
1035 		// ggf. Default-Item besorgen
1036 		if ( eState == SFX_ITEM_DEFAULT )
1037 		{
1038 			if ( SfxItemPool::IsWhich(nSlotId) )
1039 				pItem = &rPool.GetDefaultItem(nSlotId);
1040 			else
1041 				eState = SFX_ITEM_DONTCARE;
1042 		}
1043 	}
1044 	else
1045 		eState = SFX_ITEM_UNKNOWN;
1046 
1047 	// Item und Item-Status auswerten und ggf. in pStateSet mitpflegen
1048 	SfxPoolItem *pRetItem = 0;
1049 	if ( eState <= SFX_ITEM_DISABLED )
1050 	{
1051 		if ( pStateSet )
1052 			pStateSet->DisableItem(nSlotId);
1053 		return 0;
1054 	}
1055 	else if ( eState == SFX_ITEM_DONTCARE )
1056 	{
1057 		if ( pStateSet )
1058 			pStateSet->ClearItem(nSlotId);
1059 		pRetItem = new SfxVoidItem(0);
1060 	}
1061 	else
1062 	{
1063 		if ( pStateSet && pStateSet->Put( *pItem ) )
1064 			return &pStateSet->Get( pItem->Which() );
1065 		pRetItem = pItem->Clone();
1066 	}
1067 	DeleteItemOnIdle(pRetItem);
1068 
1069 	return pRetItem;
1070 }
1071 
1072 //--------------------------------------------------------------------
1073 
SFX_EXEC_STUB(SfxShell,VerbExec)1074 SFX_EXEC_STUB(SfxShell, VerbExec)
1075 SFX_STATE_STUB(SfxShell, VerbState)
1076 
1077 void SfxShell::SetVerbs(const com::sun::star::uno::Sequence < com::sun::star::embed::VerbDescriptor >& aVerbs)
1078 {
1079 	SfxViewShell *pViewSh = PTR_CAST ( SfxViewShell, this);
1080 
1081 	DBG_ASSERT(pViewSh, "SetVerbs nur an der ViewShell aufrufen!");
1082     if ( !pViewSh )
1083         return;
1084 
1085     // Zun"achst alle Statecaches dirty machen, damit keiner mehr versucht,
1086     // die Slots zu benutzen
1087     {
1088         SfxBindings *pBindings =
1089             pViewSh->GetViewFrame()->GetDispatcher()->GetBindings();
1090         sal_uInt16 nCount = pImp->aSlotArr.Count();
1091         for (sal_uInt16 n1=0; n1<nCount ; n1++)
1092         {
1093             sal_uInt16 nId = SID_VERB_START + n1;
1094             pBindings->Invalidate(nId, sal_False, sal_True);
1095         }
1096     }
1097 
1098     sal_uInt16 nr=0;
1099     for (sal_Int32 n=0; n<aVerbs.getLength(); n++)
1100     {
1101         sal_uInt16 nSlotId = SID_VERB_START + nr++;
1102         DBG_ASSERT(nSlotId <= SID_VERB_END, "Zuviele Verben!");
1103         if (nSlotId > SID_VERB_END)
1104             break;
1105 
1106         SfxSlot *pNewSlot = new SfxSlot;
1107         pNewSlot->nSlotId = nSlotId;
1108         pNewSlot->nGroupId = 0;
1109 
1110         // Verb-Slots m"ussen asynchron ausgef"uhrt werden, da sie w"ahrend
1111         // des Ausf"uhrens zerst"ort werden k"onnten
1112         pNewSlot->nFlags = SFX_SLOT_ASYNCHRON | SFX_SLOT_CONTAINER;
1113         pNewSlot->nMasterSlotId = 0;
1114         pNewSlot->nValue = 0;
1115         pNewSlot->fnExec = SFX_STUB_PTR(SfxShell,VerbExec);
1116         pNewSlot->fnState = SFX_STUB_PTR(SfxShell,VerbState);
1117         pNewSlot->pType = 0; HACK(SFX_TYPE(SfxVoidItem))
1118         pNewSlot->pName = OUStringToOString( aVerbs[n].VerbName, RTL_TEXTENCODING_UTF8).getStr(); // TODO: life time of temp is suspicious!!!
1119         pNewSlot->pLinkedSlot = 0;
1120         pNewSlot->nArgDefCount = 0;
1121         pNewSlot->pFirstArgDef = 0;
1122         pNewSlot->pUnoName = 0;
1123 
1124         if (pImp->aSlotArr.Count())
1125         {
1126             SfxSlot *pSlot = (pImp->aSlotArr)[0];
1127             pNewSlot->pNextSlot = pSlot->pNextSlot;
1128             pSlot->pNextSlot = pNewSlot;
1129         }
1130         else
1131             pNewSlot->pNextSlot = pNewSlot;
1132 
1133         pImp->aSlotArr.Insert(pNewSlot, (sal_uInt16) n);
1134 	}
1135 
1136     pImp->aVerbList = aVerbs;
1137 
1138     if (pViewSh)
1139 	{
1140 		// Der Status von SID_OBJECT wird im Controller direkt an der Shell
1141 		// abgeholt, es reicht also, ein neues StatusUpdate anzuregen
1142 		SfxBindings *pBindings = pViewSh->GetViewFrame()->GetDispatcher()->
1143 				GetBindings();
1144 		pBindings->Invalidate( SID_OBJECT, sal_True, sal_True );
1145 	}
1146 }
1147 
1148 //--------------------------------------------------------------------
1149 
GetVerbs() const1150 const com::sun::star::uno::Sequence < com::sun::star::embed::VerbDescriptor >& SfxShell::GetVerbs() const
1151 {
1152     return pImp->aVerbList;
1153 }
1154 
1155 //--------------------------------------------------------------------
1156 
VerbExec(SfxRequest & rReq)1157 void SfxShell::VerbExec(SfxRequest& rReq)
1158 {
1159 	sal_uInt16 nId = rReq.GetSlot();
1160 	SfxViewShell *pViewShell = GetViewShell();
1161 	if ( pViewShell )
1162 	{
1163         sal_Bool bReadOnly = pViewShell->GetObjectShell()->IsReadOnly();
1164         com::sun::star::uno::Sequence < com::sun::star::embed::VerbDescriptor > aList = pViewShell->GetVerbs();
1165         for (sal_Int32 n=0, nVerb=0; n<aList.getLength(); n++)
1166 		{
1167             // check for ReadOnly verbs
1168             if ( bReadOnly && !(aList[n].VerbAttributes & embed::VerbAttributes::MS_VERBATTR_NEVERDIRTIES) )
1169                 continue;
1170 
1171             // check for verbs that shouldn't appear in the menu
1172             if ( !(aList[n].VerbAttributes & embed::VerbAttributes::MS_VERBATTR_ONCONTAINERMENU) )
1173                 continue;
1174 
1175             if (nId == SID_VERB_START + nVerb++)
1176 			{
1177                 pViewShell->DoVerb(aList[n].VerbID);
1178 				rReq.Done();
1179 				return;
1180 			}
1181 		}
1182 	}
1183 }
1184 
1185 //--------------------------------------------------------------------
1186 
VerbState(SfxItemSet &)1187 void SfxShell::VerbState(SfxItemSet& )
1188 {
1189 }
1190 
1191 //--------------------------------------------------------------------
1192 
GetVerbSlot_Impl(sal_uInt16 nId) const1193 const SfxSlot* SfxShell::GetVerbSlot_Impl(sal_uInt16 nId) const
1194 {
1195     com::sun::star::uno::Sequence < com::sun::star::embed::VerbDescriptor > rList = pImp->aVerbList;
1196 
1197 	DBG_ASSERT(nId >= SID_VERB_START && nId <= SID_VERB_END,"Falsche VerbId!");
1198 	sal_uInt16 nIndex = nId - SID_VERB_START;
1199     DBG_ASSERT(nIndex < rList.getLength(),"Falsche VerbId!");
1200 
1201     if (nIndex < rList.getLength())
1202         return pImp->aSlotArr[nIndex];
1203 	else
1204 		return 0;
1205 }
1206 
1207 //--------------------------------------------------------------------
1208 
SetHelpId(sal_uIntPtr nId)1209 void SfxShell::SetHelpId(sal_uIntPtr nId)
1210 {
1211 	pImp->nHelpId = nId;
1212 }
1213 
1214 //--------------------------------------------------------------------
1215 
GetHelpId() const1216 sal_uIntPtr SfxShell::GetHelpId() const
1217 {
1218 	return pImp->nHelpId;
1219 }
1220 
1221 //--------------------------------------------------------------------
1222 
GetObjectShell()1223 SfxObjectShell* SfxShell::GetObjectShell()
1224 {
1225 	if ( GetViewShell() )
1226 		return GetViewShell()->GetViewFrame()->GetObjectShell();
1227 	else
1228 		return NULL;
1229 }
1230 
1231 //--------------------------------------------------------------------
1232 
HasUIFeature(sal_uInt32)1233 sal_Bool SfxShell::HasUIFeature( sal_uInt32 )
1234 {
1235 	return sal_False;
1236 }
1237 
DispatcherUpdate_Impl(void *,void * pArg)1238 long DispatcherUpdate_Impl( void*, void* pArg )
1239 {
1240 	((SfxDispatcher*) pArg)->Update_Impl( sal_True );
1241     ((SfxDispatcher*) pArg)->GetBindings()->InvalidateAll(sal_False);
1242 	return 0;
1243 }
1244 
UIFeatureChanged()1245 void SfxShell::UIFeatureChanged()
1246 {
1247 	SfxViewFrame *pFrame = GetFrame();
1248     if ( pFrame && pFrame->IsVisible() )
1249 	{
1250 		// Auch dann Update erzwingen, wenn Dispatcher schon geupdated ist,
1251 		// sonst bleibt evtl. irgendwas in den gebunkerten Tools stecken.
1252 		// Asynchron aufrufen, um Rekursionen zu vermeiden
1253 		if ( !pImp->pUpdater )
1254             pImp->pUpdater = new svtools::AsynchronLink( Link( this, DispatcherUpdate_Impl ) );
1255 
1256 		// Mehrfachaufrufe gestattet
1257 		pImp->pUpdater->Call( pFrame->GetDispatcher(), sal_True );
1258 	}
1259 }
1260 
SetDisableFlags(sal_uIntPtr nFlags)1261 void SfxShell::SetDisableFlags( sal_uIntPtr nFlags )
1262 {
1263 	pImp->nDisableFlags = nFlags;
1264 }
1265 
GetDisableFlags() const1266 sal_uIntPtr SfxShell::GetDisableFlags() const
1267 {
1268 	return pImp->nDisableFlags;
1269 }
1270 
CreateItemSet(sal_uInt16)1271 SfxItemSet*	SfxShell::CreateItemSet( sal_uInt16 )
1272 {
1273 	return NULL;
1274 }
1275 
ApplyItemSet(sal_uInt16,const SfxItemSet &)1276 void SfxShell::ApplyItemSet( sal_uInt16, const SfxItemSet& )
1277 {
1278 }
1279 
SetContextName(const::rtl::OUString & rsContextName)1280 void SfxShell::SetContextName (const ::rtl::OUString& rsContextName)
1281 {
1282     pImp->maContextChangeBroadcaster.Initialize(rsContextName);
1283 }
1284 
SetViewShell_Impl(SfxViewShell * pView)1285 void SfxShell::SetViewShell_Impl( SfxViewShell* pView )
1286 {
1287     pImp->pViewSh = pView;
1288 }
1289 
1290 
1291 
1292 
BroadcastContextForActivation(const bool bIsActivated)1293 void SfxShell::BroadcastContextForActivation (const bool bIsActivated)
1294 {
1295     SfxViewFrame* pViewFrame = GetFrame();
1296     if (pViewFrame != NULL)
1297         if (bIsActivated)
1298             pImp->maContextChangeBroadcaster.Activate(pViewFrame->GetFrame().GetFrameInterface());
1299         else
1300             pImp->maContextChangeBroadcaster.Deactivate(pViewFrame->GetFrame().GetFrameInterface());
1301 }
1302 
1303 
1304 
1305 
SetContextBroadcasterEnabled(const bool bIsEnabled)1306 bool SfxShell::SetContextBroadcasterEnabled (const bool bIsEnabled)
1307 {
1308     return pImp->maContextChangeBroadcaster.SetBroadcasterEnabled(bIsEnabled);
1309 }
1310