xref: /aoo41x/main/sfx2/source/control/dispatch.cxx (revision cdf0e10c)
1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_sfx2.hxx"
30 #include <com/sun/star/beans/XPropertySet.hpp>
31 #include <com/sun/star/frame/XDispatchRecorderSupplier.hpp>
32 #include <com/sun/star/frame/XLayoutManager.hpp>
33 #include <svl/itempool.hxx>
34 #include <svl/itemiter.hxx>
35 #include <svl/whiter.hxx>
36 #include <svl/intitem.hxx>
37 #ifndef _SFXEITEM_HXX //autogen
38 #include <svl/eitem.hxx>
39 #endif
40 #include <svl/undo.hxx>
41 #ifndef _WRKWIN_HXX //autogen
42 #include <vcl/wrkwin.hxx>
43 #endif
44 #include <svtools/ttprops.hxx>
45 #include <stdio.h>
46 #include <stdarg.h>
47 #include <stdlib.h>				// wg. bsearch
48 
49 #define _SVSTDARR_ULONGS
50 #include <svl/svstdarr.hxx>
51 #include <svtools/helpopt.hxx>
52 #include <com/sun/star/frame/XLayoutManager.hpp>
53 #include <com/sun/star/beans/XPropertySet.hpp>
54 
55 #ifndef GCC
56 #endif
57 
58 // wg. nAutoPageID
59 #include "appdata.hxx"
60 #include "sfx2/sfxhelp.hxx"
61 #include <sfx2/dispatch.hxx>
62 #include <sfx2/minstack.hxx>
63 #include <sfx2/msg.hxx>
64 #include <sfx2/objface.hxx>
65 #include <sfx2/bindings.hxx>
66 #include <sfx2/request.hxx>
67 #include <sfx2/app.hxx>
68 #include <sfx2/hintpost.hxx>
69 #include "slotserv.hxx"
70 #include <sfx2/ipclient.hxx>
71 #include "sfxtypes.hxx"
72 #include <sfx2/viewfrm.hxx>
73 #include <sfx2/viewsh.hxx>
74 #include <sfx2/childwin.hxx>
75 #include <sfx2/docfac.hxx>
76 #include <sfx2/msgpool.hxx>
77 #include <sfx2/module.hxx>
78 #include <sfx2/viewfrm.hxx>
79 #include <sfx2/sfxuno.hxx>
80 #include <sfx2/docfile.hxx>
81 #include <sfx2/mnumgr.hxx>
82 #include "workwin.hxx"
83 
84 namespace css = ::com::sun::star;
85 
86 //==================================================================
87 DBG_NAME(SfxDispatcherFlush)
88 DBG_NAME(SfxDispatcherFillState)
89 
90 //==================================================================
91 typedef SfxRequest* SfxRequestPtr;
92 SV_IMPL_PTRARR( SfxItemPtrArray, SfxPoolItemPtr );
93 SV_DECL_PTRARR_DEL( SfxRequestPtrArray, SfxRequestPtr, 4, 4 )
94 SV_IMPL_PTRARR( SfxRequestPtrArray, SfxRequestPtr );
95 
96 DECL_PTRSTACK(SfxShellStack_Impl, SfxShell*, 8, 4 );
97 //==================================================================
98 
99 struct SfxToDo_Impl
100 {
101 	SfxShell*			pCluster;
102 	bool               	bPush;
103 	bool    			bDelete;
104 	bool    			bUntil;
105 
106 	SfxToDo_Impl()
107 		: pCluster(0)
108 		, bPush(false)
109 		, bDelete(false)
110 		, bUntil(false)
111 				{}
112 	SfxToDo_Impl( bool bOpPush, bool bOpDelete, bool bOpUntil, SfxShell& rCluster )
113 		: pCluster(&rCluster)
114 		, bPush(bOpPush)
115 		, bDelete(bOpDelete)
116 		, bUntil(bOpUntil)
117 				{}
118 	~SfxToDo_Impl(){}
119 
120 	bool operator==( const SfxToDo_Impl& rWith ) const
121 	{ return pCluster==rWith.pCluster && bPush==rWith.bPush; }
122 };
123 
124 DECL_OBJSTACK(SfxToDoStack_Impl, SfxToDo_Impl, 8, 4);
125 IMPL_OBJSTACK(SfxToDoStack_Impl, SfxToDo_Impl);
126 
127 struct SfxObjectBars_Impl
128 {
129 	sal_uInt32          nResId;	// Resource - und ConfigId der Toolbox
130 	sal_uInt16          nMode;	// spezielle Sichtbarkeitsflags
131 	String   			aName;
132 	SfxInterface*		pIFace;
133 
134 	SfxObjectBars_Impl() :
135 		nResId( 0 )
136 	{}
137 };
138 
139 //------------------------------------------------------------------
140 
141 struct SfxDispatcher_Impl
142 {
143     SfxRequestPtrArray      aReqArr;
144 	const SfxSlotServer* pCachedServ1;		 // zuletzt gerufene Message
145 	const SfxSlotServer* pCachedServ2;		 // vorletzt gerufene Message
146 	SfxShellStack_Impl		aStack; 			// aktive Funktionalitaet
147 	Timer					aTimer; 			// fuers flushen
148 	SfxToDoStack_Impl		aToDoStack; 		// nicht abgearb. Push/Pop
149 	SfxViewFrame*           pFrame;         	// 0 oder zugeh"or. Frame
150 	SfxDispatcher*			pParent;			// z.B. AppDispatcher, ggf. 0
151 	SfxHintPosterRef		xPoster;			// asynchrones Execute
152 	sal_Bool                    bFlushing;      	// sal_True waehrend Flush //?
153 	sal_Bool					bUpdated;			// Update_Impl gelaufen
154 	sal_Bool                    bLocked;        	// kein Execute
155 	sal_Bool					bInvalidateOnUnlock;// da fragte jemand
156 	sal_Bool					bActive;			// nicht verwechseln mit gesetzt!
157 	sal_Bool*   				pInCallAliveFlag;   // dem Stack den Dtor anzeigen
158 	SfxObjectBars_Impl		aObjBars[SFX_OBJECTBAR_MAX];
159 	SfxObjectBars_Impl		aFixedObjBars[SFX_OBJECTBAR_MAX];
160 	SvULongs				aChildWins;
161 	sal_uInt32					nEventId;			// EventId UserEvent
162 	sal_Bool					bUILocked;			// Update abgeklemmt (!zappeln)
163 	sal_Bool					bNoUI;				// UI nur vom Parent Dispatcher
164 	sal_Bool					bReadOnly;			// Dokument ist ReadOnly
165 	sal_Bool					bQuiet;             // nur parent dispatcher verwenden
166 	sal_Bool					bModal;             // nur Slots vom Parent-Dispatcher
167 
168 	sal_Bool					bFilterEnabling;	// sal_True=filter enabled slots, 2==ReadOnlyDoc uebersteuert
169 	sal_uInt16					nFilterCount;		// Anzahl der SIDs in pFilterSIDs
170 	const sal_uInt16*			pFilterSIDs;		// sortiertes Array von SIDs
171 	sal_uInt16					nStandardMode;		// ExecuteMode f. PlugInDispatcher
172 	SvUShorts*				pDisableList;
173 	sal_uInt32					nDisableFlags;
174 };
175 
176 #define NO_OBJECTBAR	0
177 #define OWN_OBJECTBAR	1
178 #define OTHER_OBJECTBAR 2
179 
180 //------------------------------------------------------------------
181 
182 #define SFX_FLUSH_TIMEOUT    50
183 
184 //====================================================================
185 sal_Bool SfxDispatcher::IsLocked( sal_uInt16 ) const
186 
187 /*  [Beschreibung]
188 
189 	Mit dieser Methode kann festgestellt werden, ob der SfxDispatcher
190 	gesperrt oder freigegeben ist. Ein gesperrter SfxDispatcher
191 	f"uhrt keine <SfxRequest>s mehr aus und liefert keine
192 	Status-Informationen mehr. Er verh"alt sich so als w"aren alle
193 	Slots disabled.
194 
195 	Der Dispatcher gilt auch als gesperrt, wenn alle Dispatcher
196 	gelockt sind (<SfxApplication::LockDispatcher()>) oder der zugeh"orige
197 	Top-Frame im modal-mode ist und der angegebene Slot Frame-spezifisch
198 	(also nicht von der Application) bedient wird.
199 */
200 
201 {
202     return pImp->bLocked;
203 }
204 
205 //--------------------------------------------------------------------
206 sal_Bool SfxDispatcher::IsAppDispatcher() const
207 
208 /*	[Beschreibung]
209 
210 	Mit dieser Methode l"a\st sich festellen, ob der SfxDispacher der
211 	Applikations-Dispatcher ist.
212 
213 
214 	[R"uckgabewert]
215 
216 	sal_Bool				sal_True
217 						Es ist der Applikations-Dispatcher.
218 
219 						sal_False
220 						Es ist ein Dispatcher eines SfxViewFrame.
221 */
222 
223 {
224     return !pImp->pFrame;
225 }
226 
227 //--------------------------------------------------------------------
228 int SfxDispatcher::Call_Impl( SfxShell& rShell, const SfxSlot &rSlot, SfxRequest &rReq, sal_Bool bRecord )
229 
230 /*	[Beschreibung]
231 
232 	Hilfsfunktion zum pr"ufen, ob ein Slot executed werden darf und
233 	der Execution selbst.
234 */
235 
236 {
237 	SFX_STACK(SfxDispatcher::Call_Impl);
238 
239 	// darf der Slot gerufen werden (i.S.v. enabled)
240 	if ( rSlot.IsMode(SFX_SLOT_FASTCALL) || rShell.CanExecuteSlot_Impl(rSlot) )
241 	{
242         if ( GetFrame() )
243         {
244             // ggf. Recording anwerfen
245             com::sun::star::uno::Reference< com::sun::star::frame::XFrame > xFrame(
246                     GetFrame()->GetFrame().GetFrameInterface(),
247                     com::sun::star::uno::UNO_QUERY);
248 
249             com::sun::star::uno::Reference< com::sun::star::beans::XPropertySet > xSet(
250                     xFrame,
251                     com::sun::star::uno::UNO_QUERY);
252 
253 			if ( xSet.is() )
254 			{
255 				com::sun::star::uno::Any aProp = xSet->getPropertyValue(::rtl::OUString::createFromAscii("DispatchRecorderSupplier"));
256 	            com::sun::star::uno::Reference< com::sun::star::frame::XDispatchRecorderSupplier > xSupplier;
257 	            com::sun::star::uno::Reference< com::sun::star::frame::XDispatchRecorder > xRecorder;
258 	            aProp >>= xSupplier;
259 	            if(xSupplier.is())
260 	                xRecorder = xSupplier->getDispatchRecorder();
261 
262 	            if ( bRecord && xRecorder.is() && !rSlot.IsMode(SFX_SLOT_NORECORD) )
263 	                rReq.Record_Impl( rShell, rSlot, xRecorder, GetFrame() );
264 			}
265         }
266 
267 		// Alles holen, was gebraucht wird, da der Slot den Execute evtl. nicht
268 		// "uberlebt, falls es ein 'Pseudoslot' f"ur Macros oder Verben ist
269 		sal_Bool bAutoUpdate = rSlot.IsMode(SFX_SLOT_AUTOUPDATE);
270 
271 		// API-Call-Klammerung und Document-Lock w"ahrend des Calls
272 		{
273 			// 'this' mu\s im Dtor bescheid sagen
274 			sal_Bool bThisDispatcherAlive = sal_True;
275 			sal_Bool *pOldInCallAliveFlag = pImp->pInCallAliveFlag;
276 			pImp->pInCallAliveFlag = &bThisDispatcherAlive;
277 
278             SfxViewFrame* pView = GetFrame();
279             if ( !pView )
280                 pView = SfxViewFrame::Current();
281             if ( pView )
282             {
283                 rtl::OString aCmd(".uno:");
284                 aCmd += rSlot.GetUnoName();
285                 SfxHelp::OpenHelpAgent( &pView->GetFrame(), aCmd );
286             }
287 
288             SfxExecFunc pFunc = rSlot.GetExecFnc();
289             rShell.CallExec( pFunc, rReq );
290 
291 			// falls 'this' noch lebt
292 			if ( bThisDispatcherAlive )
293 				pImp->pInCallAliveFlag = pOldInCallAliveFlag;
294 			else
295             {
296                 if ( pOldInCallAliveFlag )
297                 {
298                     // auch verschachtelte Stack-Frames sch"utzen
299                     *pOldInCallAliveFlag = sal_False;
300                 }
301 
302                 // do nothing after this object is dead
303                 return rReq.IsDone();
304             }
305 		}
306 
307 		if ( rReq.IsDone() )
308 		{
309             SfxBindings *pBindings = GetBindings();
310 
311 			// bei AutoUpdate sofort updaten; "Pseudoslots" d"urfen nicht
312 			// Autoupdate sein!
313             if ( bAutoUpdate && pBindings )
314 			{
315 				const SfxSlot* pSlave = rSlot.GetLinkedSlot();
316 				if (pSlave)
317 				{
318 					// bei Enum-Slots irgendeinen gebundenen Slave-Slot nehmen
319 					while (!pBindings->IsBound(pSlave->GetSlotId()) && pSlave != &rSlot )
320 						pSlave = pSlave->GetLinkedSlot();
321 					pBindings->Invalidate(pSlave->GetSlotId());
322 					pBindings->Update(pSlave->GetSlotId());
323 				}
324 				else
325 				{
326 					pBindings->Invalidate(rSlot.GetSlotId());
327 					pBindings->Update(rSlot.GetSlotId());
328 				}
329 			}
330 
331 			return sal_True;
332 		}
333 	}
334 
335 	return sal_False;
336 }
337 
338 //====================================================================
339 void SfxDispatcher::Construct_Impl( SfxDispatcher* pParent )
340 {
341 	pImp = new SfxDispatcher_Impl;
342 	bFlushed = sal_True;
343 	SfxApplication *pSfxApp = SFX_APP();
344 
345 	pImp->pCachedServ1 = 0;
346 	pImp->pCachedServ2 = 0;
347 	pImp->bFlushing = sal_False;
348 	pImp->bUpdated = sal_False;
349 	pImp->bLocked = sal_False;
350 	pImp->bActive = sal_False;
351 	pImp->pParent = NULL;
352 	pImp->bUILocked = sal_False;
353 	pImp->bNoUI = sal_False;
354 	pImp->bReadOnly = sal_False;
355 	pImp->bQuiet = sal_False;
356 	pImp->bModal = sal_False;
357 	pImp->pInCallAliveFlag = 0;
358 	pImp->bFilterEnabling = sal_False;
359 	pImp->nFilterCount = 0;
360 	pImp->pFilterSIDs = 0;
361 	pImp->nStandardMode = 0;
362 	pImp->pDisableList = pSfxApp->GetDisabledSlotList_Impl();
363 	pImp->nDisableFlags = 0;
364 
365 	pImp->pParent = pParent;
366 
367 	pImp->bInvalidateOnUnlock = sal_False;
368 
369 	for (sal_uInt16 n=0; n<SFX_OBJECTBAR_MAX; n++)
370 		pImp->aObjBars[n].nResId = 0;
371 
372 	GenLink aGenLink( LINK(this, SfxDispatcher, PostMsgHandler) );
373 
374 	pImp->xPoster = new SfxHintPoster(aGenLink);
375 
376 	pImp->aTimer.SetTimeout(SFX_FLUSH_TIMEOUT);
377 	pImp->aTimer.SetTimeoutHdl( LINK(this, SfxDispatcher, EventHdl_Impl ) );
378 }
379 
380 SfxDispatcher::SfxDispatcher( SfxDispatcher* pParent )
381 {
382 	Construct_Impl( pParent );
383 	pImp->pFrame = 0;
384 }
385 
386 SfxDispatcher::SfxDispatcher( SfxViewFrame *pViewFrame )
387 
388 /*	[Beschreibung]
389 
390 	Der Konstruktor der Klasse SfxDispatcher legt einen leeren Stack
391 	von <SfxShell>-Pointern an. Er ist initial nicht gelockt und gilt als
392 	geflusht.
393 */
394 
395 {
396 	if ( pViewFrame )
397 	{
398 		SfxViewFrame *pFrame = pViewFrame->GetParentViewFrame();
399 		if ( pFrame )
400 			Construct_Impl(  pFrame->GetDispatcher() );
401         else
402             Construct_Impl( 0 );
403 	}
404 	else
405 		Construct_Impl( 0 );
406 	pImp->pFrame = pViewFrame;
407 }
408 
409 //====================================================================
410 SfxDispatcher::~SfxDispatcher()
411 
412 /*	[Beschreibung]
413 
414 	Der Destruktor der Klasse SfxDispatcher darf nicht gerufen werden,
415 	wenn die SfxDispatcher-Instanz aktiv ist. Es d"urfen sich allerdings
416 	noch <SfxShell>-Pointer auf dem Stack befinden.
417 */
418 
419 {
420 #ifdef DBG_UTIL
421 	ByteString sTemp( "Delete Dispatcher " );
422 	sTemp += ByteString::CreateFromInt64( (sal_uIntPtr)this );
423 	DBG_TRACE( sTemp.GetBuffer() );
424 	DBG_ASSERT( !pImp->bActive, "deleting active Dispatcher" );
425 #endif
426 
427 	// Damit in LeaveRegistrations kein Timer per Reschedule in PlugComm
428 	// zuschlaegt
429 	pImp->aTimer.Stop();
430 	pImp->xPoster->SetEventHdl( Link() );
431 
432 	// die Stack-Varialblem in Call_Impl benachrichtigen
433 	if ( pImp->pInCallAliveFlag )
434 		*pImp->pInCallAliveFlag = sal_False;
435 
436 	// Bindings und App besorgen
437 	SfxApplication *pSfxApp = SFX_APP();
438     SfxBindings* pBindings = GetBindings();
439 
440 //	if (pImp->nEventId)
441 //		pSfxApp->RemoveEventHdl(pImp->nEventId);
442 
443 	// wenn noch nicht flushed, die Bindings wiederbeleben
444     if ( pBindings && !pSfxApp->IsDowning() && !bFlushed )
445         pBindings->DLEAVEREGISTRATIONS();
446 
447 	// ggf. bei den Bindings abmelden
448     while ( pBindings )
449 	{
450         if ( pBindings->GetDispatcher_Impl() == this)
451             pBindings->SetDispatcher(0);
452         pBindings = pBindings->GetSubBindings_Impl();
453 	}
454 
455 	delete pImp;
456 }
457 
458 //====================================================================
459 void SfxDispatcher::Pop
460 (
461 	SfxShell&   rShell,     /*  Die vom Stack zu nehmende SfxShell-Instanz. */
462 
463 	sal_uInt16      nMode       /*  SFX_SHELL_POP_UNTIL
464 								Es werden auch alle "uber 'rShell' liegenenden
465 								SfxShell's vom Stack genommen.
466 
467 								SFX_SHELL_POP_DELETE
468 								Alle tats"achlich vom Stack genommenen
469 								SfxShells werden gel"oscht.
470 
471 								SFX_SHELL_PUSH (InPlace use only)
472 								Die Shell wird gepusht. */
473 )
474 /*  [Beschreibung]
475 
476 	Mit dieser Methode wird eine oder mehrere <SfxShell> vom SfxDispatcher
477 	gepoppt. Die SfxShell wird zun"achst zum poppen vermerkt und
478 	es wird ein Timer aufgesetzt. Erst bei Ablauf des Timers wird
479 	tats"achlich gepoppt (<SfxDispatcher::Flush()>) und die <SfxBindings>
480 	werden invalidiert. W"ahrend der Timer l"auft gleichen sich
481 	entgegengesetzte Push und Pop Befehle mit derselben SfxShell aus.
482 */
483 
484 {
485 	DBG_MEMTEST();
486 	DBG_ASSERT( rShell.GetInterface(),
487 				"pushing SfxShell without previous RegisterInterface()" );
488 
489 	bool bDelete = (nMode & SFX_SHELL_POP_DELETE) == SFX_SHELL_POP_DELETE;
490 	bool bUntil = (nMode & SFX_SHELL_POP_UNTIL) == SFX_SHELL_POP_UNTIL;
491 	bool bPush = (nMode & SFX_SHELL_PUSH) == SFX_SHELL_PUSH;
492 
493 	SfxApplication *pSfxApp = SFX_APP();
494 
495 #ifdef DBG_UTIL
496 	ByteString aMsg( "-SfxDispatcher(" );
497 	aMsg += ByteString::CreateFromInt64( (sal_uIntPtr) this );
498 	aMsg += bPush ? ")::Push(" : ")::Pop(";
499 	if ( rShell.GetInterface() )
500 		aMsg += rShell.GetInterface()->GetClassName();
501 	else
502 		aMsg += ByteString::CreateFromInt64( (sal_uIntPtr) &rShell );
503 	aMsg += bDelete ? ") with delete" : ")";
504     if ( bUntil ) aMsg += " (up to)";
505 	DbgTrace( aMsg.GetBuffer() );
506 #endif
507 
508 	// gleiche Shell wie on-Top des ToDo-Stacks?
509 	if ( pImp->aToDoStack.Count() && pImp->aToDoStack.Top().pCluster == &rShell )
510 	{
511 		// inverse Actions heben sich auf
512 		if ( pImp->aToDoStack.Top().bPush != bPush )
513 			pImp->aToDoStack.Pop();
514 		else
515 		{
516 			DBG_ASSERT( bPush, "SfxInterface pushed more than once" );
517 			DBG_ASSERT( !bPush, "SfxInterface popped more than once" );
518 		}
519 	}
520 	else
521 	{
522 		// ::com::sun::star::chaos::Action merken
523 		pImp->aToDoStack.Push( SfxToDo_Impl(bPush, bDelete, bUntil, rShell) );
524 		if ( bFlushed )
525 		{
526 			DBG_TRACE("Unflushed dispatcher!");
527 			bFlushed = sal_False;
528 			pImp->bUpdated = sal_False;
529 
530 			// Bindings schlafen legen
531             SfxBindings* pBindings = GetBindings();
532             if ( pBindings )
533                 pBindings->DENTERREGISTRATIONS();
534 		}
535 	}
536 
537 	if ( !pSfxApp->IsDowning() && pImp->aToDoStack.Count() )
538 	{
539 		//! if (SFX_APP()->AnyInput(INPUT_KEYBOARD | INPUT_MOUSE) )
540 		//! AnyInput haut nicht hin; hier muss noch ein Kriterium gefunden
541 		//! werden. Solange wieder immer mit Timer.
542 
543 		if (sal_True)
544 		{
545 			// Kein sofortiges Update gewuenscht
546 			pImp->aTimer.SetTimeout(SFX_FLUSH_TIMEOUT);
547 			pImp->aTimer.SetTimeoutHdl( LINK(this, SfxDispatcher, EventHdl_Impl ) );
548 			pImp->aTimer.Start();
549 		}
550 		else
551 		{
552 			// Schnellstmoegliches Update (sollte Normalfall sein)
553 			pImp->aTimer.Stop();
554 			GetpApp()->PostUserEvent(pImp->nEventId, (void*)0);
555 		}
556 	}
557 	else
558 	{
559 		// doch nichts zu tun
560 		pImp->aTimer.Stop();
561 
562 		// ggf. Bindings wieder aufwecken
563 		if ( !pImp->aToDoStack.Count() )
564 		{
565             SfxBindings* pBindings = GetBindings();
566             if ( pBindings )
567                 pBindings->DLEAVEREGISTRATIONS();
568 		}
569 	}
570 }
571 
572 //--------------------------------------------------------------------
573 
574 IMPL_LINK_INLINE_START( SfxDispatcher, EventHdl_Impl, void *, pvoid )
575 
576 /*	[Beschreibung]
577 
578 	Dieser Handler wird nach <SfxDispatcher::Invalidate()> oder Bewegungen
579 	auf dem Stack (<SfxDispatcher::Push()> und <SfxDispatcher::Pop()) gerufen.
580 
581 	Er flusht den Stack, falls er dirty ist, f"uhrt also die ausstehenden
582 	Push und Pop Befehle tats"achlich aus.
583 */
584 
585 {
586     (void)pvoid; // unused
587     DBG_MEMTEST();
588 
589 	Flush();
590 	Update_Impl();
591     SfxBindings* pBindings = GetBindings();
592     if ( pBindings )
593         pBindings->StartUpdate_Impl(sal_False);
594 	return 0;
595 }
596 IMPL_LINK_INLINE_END( SfxDispatcher, EventHdl_Impl, void *, pvoid )
597 
598 //--------------------------------------------------------------------
599 sal_Bool SfxDispatcher::CheckVirtualStack( const SfxShell& rShell, sal_Bool bDeep )
600 
601 /*	[Beschreibung]
602 
603 	Mit dieser Methode kann gepr"uft werden, ob sich die <SfxShell> rShell
604 	auf dem Stack befindet, wenn er geflusht w"are. Dabei wird der
605 	SfxDispatcher jedoch nicht tats"achlich geflusht.
606 
607 	Diese Methode ist u.a. dazu gedacht, Assertions zu erm"oglichen, ohne
608 	als Seiteneffekt den SfxDispathcer flushen zu m"ussen.
609 */
610 
611 {
612 	DBG_MEMTEST();
613 	SFX_STACK(SfxDispatcher::CheckVirtualStack);
614 
615 	SfxShellStack_Impl aStack( pImp->aStack );
616 	for ( short nToDo = pImp->aToDoStack.Count()-1; nToDo >= 0; --nToDo )
617 	{
618 		SfxToDo_Impl aToDo( pImp->aToDoStack.Top(nToDo) );
619 		if ( aToDo.bPush )
620 			aStack.Push( (SfxShell*) aToDo.pCluster );
621 		else
622 		{
623 			SfxShell* pPopped = 0;
624 			do
625 			{
626 				DBG_ASSERT( aStack.Count(), "popping from empty stack" );
627 				pPopped = aStack.Pop();
628 			}
629 			while ( aToDo.bUntil && pPopped != aToDo.pCluster );
630 			DBG_ASSERT( pPopped == aToDo.pCluster, "popping unpushed SfxInterface" );
631 		}
632 	}
633 
634 	sal_Bool bReturn;
635 	if ( bDeep )
636 		bReturn = aStack.Contains(&rShell);
637 	else
638 		bReturn = aStack.Top() == &rShell;
639 	return bReturn;
640 }
641 
642 //--------------------------------------------------------------------
643 sal_uInt16 SfxDispatcher::GetShellLevel( const SfxShell& rShell )
644 
645 /*	[Beschreibung]
646 
647 	Ermittelt die Position einer SfxShell im Stack des Dispatchers.
648 	Dazu wird dieser ggf. zuvor geflusht.
649 
650 
651     [Rueckgabewert]
652 
653 	sal_uInt16						== USRT_MAX
654 								Die SfxShell befindet sich nicht auf
655 								diesem SfxDispatcher.
656 
657 								< USHRT_MAX
658 								Position der SfxShell auf dem Dispatcher
659 								von oben mit 0 beginnend gez"ahlt.
660 */
661 
662 {
663 	DBG_MEMTEST();
664 	SFX_STACK(SfxDispatcher::GetShellLevel);
665 	Flush();
666 
667 	for ( sal_uInt16 n = 0; n < pImp->aStack.Count(); ++n )
668 		if ( pImp->aStack.Top( n ) == &rShell )
669 			return n;
670 	if ( pImp->pParent )
671     {
672         sal_uInt16 nRet = pImp->pParent->GetShellLevel(rShell);
673         if ( nRet == USHRT_MAX )
674             return nRet;
675         return  nRet + pImp->aStack.Count();
676     }
677 
678 	return USHRT_MAX;
679 }
680 
681 //--------------------------------------------------------------------
682 SfxShell *SfxDispatcher::GetShell(sal_uInt16 nIdx) const
683 
684 /*	[Beschreibung]
685 
686 	Liefert einen Pointer auf die <SfxShell>, welche sich an der Position
687 	nIdx (von oben, letzt-gepushte liegt bei 0) auf dem Stack befindet.
688 
689 	Dabei wird der SfxDispatcher nicht geflusht.
690 
691 	Ist der Stack nicht tief genug, wird ein 0-Pointer zur"uckgegeben.
692 */
693 
694 {
695 	DBG_MEMTEST();
696 
697 	sal_uInt16 nShellCount = pImp->aStack.Count();
698 	if ( nIdx < nShellCount )
699 		return pImp->aStack.Top(nIdx);
700 	else if ( pImp->pParent )
701 		return pImp->pParent->GetShell(	nIdx - nShellCount );
702 	return 0;
703 }
704 
705 //--------------------------------------------------------------------
706 SfxBindings* SfxDispatcher::GetBindings() const
707 
708 /*	[Beschreibung]
709 
710 	Diese Methode liefert einen Pointer auf die <SfxBindings> Instanz
711 	zur"uck, an die der SfxDispatcher gerade gebunden ist. Ein SfxDispatcher
712 	ist nur dann an SfxBindings gebunden, wenn er <UI-aktiv> ist. Ist
713 	er nicht UI-aktiv, wird ein 0-Pointer zur"uckgegeben.
714 
715 	Der zur"uckgegebene Pointer ist nur im <unmittelbaren Kontext> des
716 	Methodenaufrufs g"ultig.
717 */
718 
719 {
720 	if ( pImp->pFrame )
721 		return &pImp->pFrame->GetBindings();
722     else
723         return NULL;
724 }
725 
726 //--------------------------------------------------------------------
727 SfxViewFrame* SfxDispatcher::GetFrame() const
728 
729 /*	[Beschreibung]
730 
731 	Liefert einen Pointer auf die <SfxViewFrame> Instanz, der dieser
732 	SfxDispatcher geh"ort. Falls es sich um den Applikations-Dispatcher
733 	handelt, wird ein 0-Pointer zur"uckgegeben.
734 */
735 
736 {
737 	DBG_MEMTEST();
738 	return pImp->pFrame;
739 }
740 
741 //--------------------------------------------------------------------
742 void SfxDispatcher::DoActivate_Impl( sal_Bool bMDI, SfxViewFrame* /* pOld */ )
743 
744 /*	[Beschreibung]
745 
746 	Diese Methode steuert das Aktivieren eines Dispatchers.
747 
748 	Da der Applikations-Dispatcher immer aktiv ist, entweder als
749 	Unterdispatcher des <SfxViewFrame>-Dispatchers oder selbst, wird
750 	er nie als ganzes Aktiviert, sondern nur seine einzelnen <SfxShell>s
751 	bei <SfxDispatcher::Push(SfxShell&)>.
752 
753 	Beim Aktivieren eines SfxDispatchers wird an allen auf seinem
754 	Stack befindlichen SfxShells, beginnend mit der untersten, der Handler
755 	<SfxShell::Activate(sal_Bool)> gerufen.
756 */
757 
758 {
759 	DBG_MEMTEST();
760 	SFX_STACK(SfxDispatcher::DoActivate);
761 	if ( bMDI )
762 	{
763 		#ifdef DBG_UTIL
764 		ByteString sTemp("Activate Dispatcher ");
765 		sTemp += ByteString::CreateFromInt64( (sal_uIntPtr) this );
766 		DBG_TRACE(sTemp.GetBuffer());
767 		DBG_ASSERT( !pImp->bActive, "Activate-Fehler" );
768 		#endif
769 		pImp->bActive = sal_True;
770 		pImp->bUpdated = sal_False;
771         SfxBindings* pBindings = GetBindings();
772         if ( pBindings )
773         {
774             pBindings->SetDispatcher(this);
775             pBindings->SetActiveFrame( pImp->pFrame->GetFrame().GetFrameInterface() );
776         }
777 	}
778 	else
779 	{
780 		#ifdef DBG_UTIL
781 		ByteString sTemp("Non-MDI-Activate Dispatcher");
782 		sTemp += ByteString::CreateFromInt64( (sal_uIntPtr) this );
783 		DBG_TRACE( sTemp.GetBuffer() );
784 		#endif
785 	}
786 
787 	if ( IsAppDispatcher() )
788 		return;
789 
790 	for ( int i = int(pImp->aStack.Count()) - 1; i >= 0; --i )
791 		pImp->aStack.Top( (sal_uInt16) i )->DoActivate_Impl(pImp->pFrame, bMDI);
792 
793     if ( bMDI && pImp->pFrame )
794     {
795         //SfxWorkWindow *pWorkWin = pImp->pFrame->GetFrame().GetWorkWindow_Impl();
796         SfxBindings *pBind = GetBindings();
797         while ( pBind )
798         {
799             pBind->HidePopupCtrls_Impl( sal_False );
800             pBind = pBind->GetSubBindings_Impl();
801         }
802 
803         pImp->pFrame->GetFrame().GetWorkWindow_Impl()->HidePopups_Impl( sal_False, sal_False, 1 );
804     }
805 
806 	if ( pImp->aToDoStack.Count() )
807 	{
808 		if (sal_True)
809 		{
810 			// Kein sofortiges Update gewuenscht
811 			pImp->aTimer.SetTimeout(SFX_FLUSH_TIMEOUT);
812 			pImp->aTimer.SetTimeoutHdl( LINK(this, SfxDispatcher, EventHdl_Impl ) );
813 			pImp->aTimer.Start();
814 		}
815 		else
816 		{
817 			// Schnellstmoegliches Update (sollte Normalfall sein)
818 			pImp->aTimer.Stop();
819 			GetpApp()->PostUserEvent(pImp->nEventId, (void*)0);
820 		}
821 	}
822 }
823 
824 void SfxDispatcher::DoParentActivate_Impl()
825 {
826 	for ( int i = int(pImp->aStack.Count()) - 1; i >= 0; --i )
827 		pImp->aStack.Top( (sal_uInt16) i )->ParentActivate();
828 }
829 
830 //--------------------------------------------------------------------
831 void SfxDispatcher::DoDeactivate_Impl( sal_Bool bMDI, SfxViewFrame* pNew )
832 
833 /*  [Beschreibung]
834 
835 	Diese Methode steuert das Deaktivieren eines Dispatchers.
836 
837 	Da der Applikations-Dispatcher immer aktiv ist, entweder als
838 	Unterdispatcher des <SfxViewFrame>-Dispatchers oder selbst, wird
839 	er nie als ganzes Deaktiviert, sondern nur seine einzelnen <SfxShell>s
840 	bei <SfxDispatcher::Pop(SfxShell&)>.
841 
842 	Beim Deaktivieren eines SfxDispatchers wird an allen auf seinem
843 	Stack befindlichen SfxShells, beginnend mit der obersten, der Handler
844 	<SfxShell::Deactivate(sal_Bool)> gerufen.
845 */
846 
847 {
848 	DBG_MEMTEST();
849 	SFX_STACK(SfxDispatcher::DoDeactivate);
850 
851 	SfxApplication *pSfxApp = SFX_APP();
852 
853 	if ( bMDI )
854 	{
855 		DBG_TRACE(ByteString("Deactivate Dispatcher ").Append(ByteString::CreateFromInt64( (sal_uIntPtr) this )).GetBuffer());
856 		DBG_ASSERT( pImp->bActive, "Deactivate-Fehler" );
857 		pImp->bActive = sal_False;
858 
859         if ( pImp->pFrame && !(pImp->pFrame->GetObjectShell()->IsInPlaceActive() ) )
860 		{
861             SfxWorkWindow *pWorkWin = pImp->pFrame->GetFrame().GetWorkWindow_Impl();
862             if ( pWorkWin )
863             {
864                 for (sal_uInt16 n=0; n<pImp->aChildWins.Count();)
865                 {
866                     SfxChildWindow *pWin = pWorkWin->GetChildWindow_Impl( (sal_uInt16) ( pImp->aChildWins[n] & 0xFFFF ) );
867                     if (!pWin || (pWin && pWin->GetAlignment() == SFX_ALIGN_NOALIGNMENT))
868                         pImp->aChildWins.Remove(n);
869                     else
870                         n++;
871                 }
872             }
873 		}
874 	}
875 	else {
876 		DBG_TRACE( ByteString ("Non-MDI-DeActivate Dispatcher").Append(ByteString::CreateFromInt64( (sal_uIntPtr) this )).GetBuffer() );
877     }
878 
879 	if ( IsAppDispatcher() && !pSfxApp->IsDowning() )
880 		return;
881 
882 	for ( sal_uInt16 i = 0; i < pImp->aStack.Count(); ++i )
883 		pImp->aStack.Top(i)->DoDeactivate_Impl(pImp->pFrame, bMDI);
884 
885     sal_Bool bHidePopups = bMDI && pImp->pFrame;
886     if ( pNew && pImp->pFrame )
887     {
888         com::sun::star::uno::Reference< com::sun::star::frame::XFrame > xOldFrame(
889             pNew->GetFrame().GetFrameInterface()->getCreator(), com::sun::star::uno::UNO_QUERY );
890 
891         com::sun::star::uno::Reference< com::sun::star::frame::XFrame > xMyFrame(
892             GetFrame()->GetFrame().GetFrameInterface(), com::sun::star::uno::UNO_QUERY );
893 
894         if ( xOldFrame == xMyFrame )
895             bHidePopups = sal_False;
896     }
897 
898     if ( bHidePopups )
899     {
900         //SfxWorkWindow *pWorkWin = pImp->pFrame->GetFrame().GetWorkWindow_Impl();
901         SfxBindings *pBind = GetBindings();
902         while ( pBind )
903         {
904             pBind->HidePopupCtrls_Impl( sal_True );
905             pBind = pBind->GetSubBindings_Impl();
906         }
907 
908         pImp->pFrame->GetFrame().GetWorkWindow_Impl()->HidePopups_Impl( sal_True, sal_False, 1 );
909     }
910 
911 	Flush();
912 }
913 
914 void SfxDispatcher::DoParentDeactivate_Impl()
915 {
916 	for ( int i = int(pImp->aStack.Count()) - 1; i >= 0; --i )
917 		pImp->aStack.Top( (sal_uInt16) i )->ParentDeactivate();
918 }
919 
920 //--------------------------------------------------------------------
921 int SfxDispatcher::GetShellAndSlot_Impl
922 (
923 	sal_uInt16			nSlot,		// die zu suchende Slot-Id
924 	SfxShell**		ppShell,	// die SfxShell, welche nSlot z.Zt. bedient
925 	const SfxSlot** ppSlot, 	// der SfxSlot, welcher nSlot z.Zt. bedient
926 	sal_Bool			bOwnShellsOnly,
927 	sal_Bool			bModal,		// trotz ModalMode
928 	sal_Bool		bRealSlot
929 )
930 
931 /*	[Beschreibung]
932 
933 	Diese Methode sucht im SfxDispatcher nach der <SfxShell>, von der
934 	die Slot-Id nSlot zur Zeit bedient wird. Dazu wird der Dispatcher
935 	zuvor geflusht.
936 
937 
938 	[R"uckgabewert]
939 
940 	int 				sal_True
941 						Die SfxShell wurde gefunden, ppShell und ppSlot
942 						sind g"ultig.
943 
944 						sal_True
945 						Die SfxShell wurde nicht gefunden, ppShell und ppSlot
946 						sind ung"ultig.
947 */
948 
949 {
950 	SFX_STACK(SfxDispatcher::GetShellAndSlot_Impl);
951 
952 	Flush();
953 	SfxSlotServer aSvr;
954 	if ( _FindServer(nSlot, aSvr, bModal) )
955 	{
956 		if ( bOwnShellsOnly && aSvr.GetShellLevel() >= pImp->aStack.Count() )
957 			return sal_False;
958 
959 		*ppShell = GetShell(aSvr.GetShellLevel());
960 		*ppSlot = aSvr.GetSlot();
961 		if ( 0 == (*ppSlot)->GetExecFnc() && bRealSlot )
962 			*ppSlot = (*ppShell)->GetInterface()->GetRealSlot(*ppSlot);
963 		// Check only real slots as enum slots don't have an execute function!
964         if ( bRealSlot && ((0 == *ppSlot) || (0 == (*ppSlot)->GetExecFnc()) ))
965 			return sal_False;
966 
967 #ifdef DBG_UTILx
968 		ByteString aMsg( nSlot );
969 		aMsg += " found in ";
970 		aMsg += (*ppShell)->GetInterface()->GetClassName();
971 		DbgTrace( aMsg.GetBuffer() );
972 #endif
973 
974 		return sal_True;
975 	}
976 
977 #ifdef DBG_UTILx
978 	ByteString aMsg( nSlot );
979 	aMsg += " not found";
980 	DbgTrace( aMsg.GetBuffer() );
981 #endif
982 
983 	return sal_False;
984 }
985 
986 /*
987 struct Executer : public SfxHint
988 {
989     SfxRequest *pRequest;
990     const SfxSlot* pSlot;
991     sal_uInt16 nLevel;
992 
993     Executer( SfxRequest* pReq, const SfxSlot* p, sal_uInt16 n )
994         :  pRequest( pReq )
995         , pSlot(p)
996         , nLevel(n)
997         {}
998     ~Executer()
999     {delete pRequest;}
1000 };
1001 */
1002 
1003 //--------------------------------------------------------------------
1004 void SfxDispatcher::_Execute
1005 (
1006 	SfxShell&		rShell,		// zu rufende <SfxShell>
1007 	const SfxSlot&	rSlot,		// zu rufender <SfxSlot>
1008 	SfxRequest&		rReq,		// auszuf"uhrende Funktion (Id und optional Parameter)
1009 	SfxCallMode 	eCallMode	// synchron, asynchron oder wie beim Slot angegeben
1010 )
1011 
1012 /*	[Beschreibung]
1013 
1014 	Diese Methode f"uhrt einen Request "uber einen gecachten <Slot-Server>
1015 	aus.
1016 */
1017 
1018 {
1019 	DBG_MEMTEST();
1020 	DBG_ASSERT( !pImp->bFlushing, "recursive call to dispatcher" );
1021 	DBG_ASSERT( !pImp->aToDoStack.Count(), "unprepared InPlace _Execute" );
1022 
1023 	if ( IsLocked( rSlot.GetSlotId() ) )
1024 		return;
1025 
1026 	if ( (eCallMode & SFX_CALLMODE_ASYNCHRON) ||
1027 		 ( !(eCallMode & SFX_CALLMODE_SYNCHRON) &&
1028 		   rSlot.IsMode(SFX_SLOT_ASYNCHRON) ) )
1029 	{
1030 		SfxDispatcher *pDispat = this;
1031 		while ( pDispat )
1032 		{
1033 			sal_uInt16 nShellCount = pDispat->pImp->aStack.Count();
1034 			for ( sal_uInt16 n=0; n<nShellCount; n++ )
1035 			{
1036 				if ( &rShell == pDispat->pImp->aStack.Top(n) )
1037 				{
1038                     if ( eCallMode & SFX_CALLMODE_RECORD )
1039                         rReq.AllowRecording( sal_True );
1040                     pDispat->pImp->xPoster->Post(new SfxRequest(rReq));
1041 //                    pDispat->pImp->xPoster->Post(new Executer(new SfxRequest(rReq), &rSlot, n ));
1042 					return;
1043 				}
1044 			}
1045 
1046 			pDispat = pDispat->pImp->pParent;
1047 		}
1048 	}
1049 	else
1050 		Call_Impl( rShell, rSlot, rReq, SFX_CALLMODE_RECORD==(eCallMode&SFX_CALLMODE_RECORD) );
1051 }
1052 
1053 //--------------------------------------------------------------------
1054 void MappedPut_Impl( SfxAllItemSet &rSet, const SfxPoolItem &rItem )
1055 
1056 /*	[Beschreibung]
1057 
1058 	Hilfsfunktion zum putten von rItem unter der im Pool des Item-Sets
1059 	rSet geltenden Which-Id.
1060 */
1061 
1062 {
1063 	// mit ggf. gemappter Which-Id putten
1064 	const SfxItemPool *pPool = rSet.GetPool();
1065 	sal_uInt16 nWhich = rItem.Which();
1066 #ifdef TF_POOLABLE
1067 	if ( pPool->IsSlot(nWhich) )
1068 #else
1069 	if ( pPool->HasMap() && pPool->IsSlot(nWhich) )
1070 #endif
1071 		nWhich = pPool->GetWhich(nWhich);
1072 	rSet.Put( rItem, nWhich );
1073 }
1074 
1075 //--------------------------------------------------------------------
1076 
1077 #ifndef SFX_USE_BINDINGS
1078 #define SFX_USE_BINDINGS 0x8000
1079 #endif
1080 
1081 sal_uInt16 SfxDispatcher::ExecuteFunction( sal_uInt16 nSlot, SfxPoolItem **pArgs,
1082 									   sal_uInt16 nMode )
1083 {
1084 	if ( !nMode )
1085 		nMode = pImp->nStandardMode;
1086 
1087 	// via Bindings/Interceptor? (dann ist der Returnwert nicht exakt)
1088 	sal_Bool bViaBindings = SFX_USE_BINDINGS == ( nMode & SFX_USE_BINDINGS );
1089 	nMode &= ~sal_uInt16(SFX_USE_BINDINGS);
1090     if ( bViaBindings && GetBindings() )
1091 		return GetBindings()->Execute( nSlot, (const SfxPoolItem **) pArgs, nMode )
1092 				? EXECUTE_POSSIBLE
1093 				: EXECUTE_NO;
1094 
1095 	// sonst via Dispatcher
1096 	if ( IsLocked(nSlot) )
1097 		return 0;
1098 	SfxShell *pShell = 0;
1099 	SfxCallMode eCall = SFX_CALLMODE_SYNCHRON;
1100 	sal_uInt16 nRet = EXECUTE_NO;
1101 	const SfxSlot *pSlot = 0;
1102 	if ( GetShellAndSlot_Impl( nSlot, &pShell, &pSlot, sal_False, sal_False ) )
1103 	{
1104 		// Ausf"uhrbarkeit vorher testen
1105 		if ( pSlot->IsMode( SFX_SLOT_FASTCALL ) ||
1106 			pShell->CanExecuteSlot_Impl( *pSlot ) )
1107 				nRet = EXECUTE_POSSIBLE;
1108 
1109 		if ( nMode == EXECUTEMODE_ASYNCHRON )
1110 			eCall = SFX_CALLMODE_ASYNCHRON;
1111 		else if ( nMode == EXECUTEMODE_DIALOGASYNCHRON && pSlot->IsMode( SFX_SLOT_HASDIALOG ) )
1112 			eCall = SFX_CALLMODE_ASYNCHRON;
1113 		else if ( pSlot->GetMode() & SFX_SLOT_ASYNCHRON )
1114 			eCall = SFX_CALLMODE_ASYNCHRON;
1115 		sal_Bool bDone = sal_False;
1116 		if ( pArgs && *pArgs )
1117 		{
1118 			SfxAllItemSet aSet( pShell->GetPool() );
1119 			for ( SfxPoolItem **pArg = pArgs; *pArg; ++pArg )
1120 				MappedPut_Impl( aSet, **pArg );
1121 			SfxRequest aReq( nSlot, eCall, aSet );
1122 			_Execute( *pShell, *pSlot, aReq, eCall );
1123 			bDone = aReq.IsDone();
1124 		}
1125 		else
1126 		{
1127 			SfxRequest aReq( nSlot, eCall, pShell->GetPool() );
1128 			_Execute( *pShell, *pSlot, aReq, eCall );
1129 			bDone = aReq.IsDone();
1130 		}
1131 	}
1132 
1133 	return nRet;
1134 }
1135 
1136 sal_uInt16 SfxDispatcher::ExecuteFunction( sal_uInt16 nSlot, const SfxItemSet& rArgs,
1137 									   sal_uInt16 nMode )
1138 {
1139 	if ( !nMode )
1140 		nMode = pImp->nStandardMode;
1141 
1142 /*
1143     // at the moment not implemented
1144     // via Bindings/Interceptor? (dann ist der Returnwert nicht exakt)
1145 	sal_Bool bViaBindings = SFX_USE_BINDINGS == ( nMode & SFX_USE_BINDINGS );
1146 	nMode &= ~sal_uInt16(SFX_USE_BINDINGS);
1147     if ( bViaBindings && GetBindings() )
1148         return GetBindings()->Execute( nSlot, rArgs, nMode )
1149 				? EXECUTE_POSSIBLE
1150 				: EXECUTE_NO;
1151 */
1152 	// sonst via Dispatcher
1153 	if ( IsLocked(nSlot) )
1154 		return 0;
1155 	SfxShell *pShell = 0;
1156 	SfxCallMode eCall = SFX_CALLMODE_SYNCHRON;
1157 	sal_uInt16 nRet = EXECUTE_NO;
1158 	const SfxSlot *pSlot = 0;
1159 	if ( GetShellAndSlot_Impl( nSlot, &pShell, &pSlot, sal_False, sal_False ) )
1160 	{
1161 		// Ausf"uhrbarkeit vorher testen
1162 		if ( pSlot->IsMode( SFX_SLOT_FASTCALL ) ||
1163 			pShell->CanExecuteSlot_Impl( *pSlot ) )
1164 				nRet = EXECUTE_POSSIBLE;
1165 
1166 		if ( nMode == EXECUTEMODE_ASYNCHRON )
1167 			eCall = SFX_CALLMODE_ASYNCHRON;
1168 		else if ( nMode == EXECUTEMODE_DIALOGASYNCHRON && pSlot->IsMode( SFX_SLOT_HASDIALOG ) )
1169 			eCall = SFX_CALLMODE_ASYNCHRON;
1170 		else if ( pSlot->GetMode() & SFX_SLOT_ASYNCHRON )
1171 			eCall = SFX_CALLMODE_ASYNCHRON;
1172 		sal_Bool bDone = sal_False;
1173             SfxRequest aReq( nSlot, eCall, rArgs );
1174 			_Execute( *pShell, *pSlot, aReq, eCall );
1175 			bDone = aReq.IsDone();
1176 	}
1177 
1178 	return nRet;
1179 }
1180 
1181 sal_uInt16 SfxDispatcher::GetSlotId( const String& rCommand )
1182 {
1183     const SfxSlot *pSlot = GetSlot( rCommand );
1184     if ( pSlot )
1185         return pSlot->GetSlotId();
1186 	return 0;
1187 }
1188 
1189 const SfxSlot* SfxDispatcher::GetSlot( const String& rCommand )
1190 {
1191 	// Anzahl der Shells auf den verkettenten Dispatchern z"ahlen
1192 	Flush();
1193 	sal_uInt16 nTotCount = pImp->aStack.Count();
1194 	if ( pImp->pParent )
1195 	{
1196 		SfxDispatcher *pParent = pImp->pParent;
1197 		while ( pParent )
1198 		{
1199 			nTotCount = nTotCount + pParent->pImp->aStack.Count();
1200 			pParent = pParent->pImp->pParent;
1201 		}
1202 	}
1203 
1204 	const SfxSlot *pSlot=NULL;
1205 	sal_uInt16 nFirstShell = 0;
1206 	for ( sal_uInt16 i = nFirstShell; i < nTotCount; ++i )
1207 	{
1208 		SfxShell *pObjShell = GetShell(i);
1209 		SfxInterface *pIFace = pObjShell->GetInterface();
1210 		pSlot = pIFace->GetSlot( rCommand );
1211         if ( pSlot )
1212             return pSlot;
1213 	}
1214 
1215 	return 0;
1216 }
1217 
1218 //--------------------------------------------------------------------
1219 int SfxExecuteItem::operator==( const SfxPoolItem& rItem ) const
1220 {
1221 	SfxExecuteItem& rArg = (SfxExecuteItem& )rItem;
1222 	sal_uInt16 nCount = Count();
1223 	if( nCount != rArg.Count() )
1224 		return sal_False;
1225 	while( nCount -- )
1226 		if( *GetObject( nCount ) != *rArg.GetObject( nCount ) )
1227 			return sal_False;
1228 	return  eCall == rArg.eCall;
1229 }
1230 
1231 //--------------------------------------------------------------------
1232 SfxPoolItem* SfxExecuteItem::Clone( SfxItemPool* ) const
1233 {
1234 	return new SfxExecuteItem( *this );
1235 }
1236 
1237 //--------------------------------------------------------------------
1238 SfxExecuteItem::SfxExecuteItem( const SfxExecuteItem& rArg )
1239 	: SfxItemPtrArray(), SfxPoolItem( rArg ), nModifier( 0 )
1240 {
1241 	eCall = rArg.eCall;
1242 	nSlot = rArg.nSlot;
1243 	sal_uInt16 nCount = rArg.Count();
1244 	for( sal_uInt16 nPos = 0; nPos < nCount; nPos++ )
1245 		Insert( rArg[ nPos ]->Clone(), nPos );
1246 }
1247 
1248 //--------------------------------------------------------------------
1249 SfxExecuteItem::SfxExecuteItem(
1250 	sal_uInt16 nWhichId, sal_uInt16 nSlotP, SfxCallMode eModeP,
1251 	const SfxPoolItem*	pArg1, ... ) :
1252 	SfxPoolItem( nWhichId ), nSlot( nSlotP ), eCall( eModeP ), nModifier( 0 )
1253 {
1254 	va_list pVarArgs;
1255 	va_start( pVarArgs, pArg1 );
1256 	for ( const SfxPoolItem *pArg = pArg1; pArg;
1257 		  pArg = va_arg( pVarArgs, const SfxPoolItem* ) )
1258 		Insert( pArg->Clone(), Count() );
1259 	va_end(pVarArgs);
1260 }
1261 
1262 //--------------------------------------------------------------------
1263 SfxExecuteItem::SfxExecuteItem(
1264 	sal_uInt16 nWhichId, sal_uInt16 nSlotP, SfxCallMode eModeP )
1265 	: SfxPoolItem( nWhichId ), nSlot( nSlotP ), eCall( eModeP ), nModifier( 0 )
1266 {
1267 }
1268 
1269 //--------------------------------------------------------------------
1270 const SfxPoolItem* SfxDispatcher::Execute( const SfxExecuteItem& rItem )
1271 {
1272 	const SfxPoolItem** pPtr = new const SfxPoolItem*[ rItem.Count() + 1 ];
1273 	for( sal_uInt16 nPos = rItem.Count(); nPos--; )
1274 		pPtr[ nPos ] = rItem.GetObject( nPos );
1275 	pPtr[ rItem.Count() ] = 0;
1276 	const SfxPoolItem* pRet = Execute(
1277 		rItem.GetSlot(), rItem.GetCallMode(), pPtr, rItem.GetModifier() );
1278 
1279 	delete [] (SfxPoolItem**)pPtr;
1280 
1281 	return pRet;
1282 }
1283 
1284 //--------------------------------------------------------------------
1285 const SfxPoolItem*	SfxDispatcher::Execute(
1286     sal_uInt16 nSlot,
1287     SfxCallMode nCall,
1288     SfxItemSet* pArgs,
1289     SfxItemSet* pInternalArgs,
1290     sal_uInt16 nModi)
1291 {
1292 	if ( IsLocked(nSlot) )
1293 		return 0;
1294 
1295 	SfxShell *pShell = 0;
1296 	const SfxSlot *pSlot = 0;
1297 	if ( GetShellAndSlot_Impl( nSlot,  &pShell, &pSlot, sal_False,
1298 							   SFX_CALLMODE_MODAL==(nCall&SFX_CALLMODE_MODAL) ) )
1299 	{
1300 		SfxAllItemSet aSet( pShell->GetPool() );
1301 		if ( pArgs )
1302 		{
1303 		    SfxItemIter aIter(*pArgs);
1304 		    for ( const SfxPoolItem *pArg = aIter.FirstItem();
1305 			    pArg;
1306 			    pArg = aIter.NextItem() )
1307 			    MappedPut_Impl( aSet, *pArg );
1308 		}
1309 		SfxRequest aReq( nSlot, nCall, aSet );
1310         if (pInternalArgs)
1311     		aReq.SetInternalArgs_Impl( *pInternalArgs );
1312         aReq.SetModifier( nModi );
1313 
1314 		_Execute( *pShell, *pSlot, aReq, nCall );
1315 		return aReq.GetReturnValue();
1316 	}
1317 	return 0;
1318 }
1319 
1320 //--------------------------------------------------------------------
1321 const SfxPoolItem* SfxDispatcher::Execute
1322 (
1323 	sal_uInt16 nSlot,				// die Id der auszufuehrenden Funktion
1324 	SfxCallMode eCall,			// SFX_CALLMODE_SYNCRHON, ..._ASYNCHRON oder ..._SLOT
1325 	const SfxPoolItem **pArgs,	// 0-terminiertes C-Array von Parametern
1326 	sal_uInt16 nModi,
1327 	const SfxPoolItem **pInternalArgs // 0-terminiertes C-Array von Parametern
1328 )
1329 
1330 /*  [Beschreibung]
1331 
1332 	Methode zum Ausf"uhren eines <SfxSlot>s "uber die Slot-Id.
1333 
1334 
1335 	[R"uckgabewert]
1336 
1337 	const SfxPoolItem*		Pointer auf ein bis zum n"achsten Durchlauf
1338 							der Message-Loop g"ultiges SfxPoolItem,
1339 							welches den R"uckgabewert enth"alt.
1340 
1341 							Oder ein 0-Pointer, wenn die Funktion nicht
1342 							ausgef"uhrt wurde (z.B. Abbruch durch den
1343 							Benutzer).
1344 */
1345 
1346 {
1347 	if ( IsLocked(nSlot) )
1348 		return 0;
1349 
1350 	SfxShell *pShell = 0;
1351 	const SfxSlot *pSlot = 0;
1352 	if ( GetShellAndSlot_Impl( nSlot,  &pShell, &pSlot, sal_False,
1353 							   SFX_CALLMODE_MODAL==(eCall&SFX_CALLMODE_MODAL) ) )
1354 	{
1355 		SfxRequest* pReq;
1356 		if ( pArgs && *pArgs )
1357 		{
1358 			SfxAllItemSet aSet( pShell->GetPool() );
1359 			for ( const SfxPoolItem **pArg = pArgs; *pArg; ++pArg )
1360 				MappedPut_Impl( aSet, **pArg );
1361 			pReq = new SfxRequest( nSlot, eCall, aSet );
1362 		}
1363 		else
1364 			pReq =  new SfxRequest( nSlot, eCall, pShell->GetPool() );
1365 		pReq->SetModifier( nModi );
1366 		if( pInternalArgs && *pInternalArgs)
1367 		{
1368 			SfxAllItemSet aSet( SFX_APP()->GetPool() );
1369 			for ( const SfxPoolItem **pArg = pInternalArgs; *pArg; ++pArg )
1370 				aSet.Put( **pArg );
1371 			pReq->SetInternalArgs_Impl( aSet );
1372 		}
1373 		_Execute( *pShell, *pSlot, *pReq, eCall );
1374 		const SfxPoolItem* pRet = pReq->GetReturnValue();
1375 		delete pReq; return pRet;
1376 	}
1377 	return 0;
1378 }
1379 
1380 //--------------------------------------------------------------------
1381 const SfxPoolItem* SfxDispatcher::Execute
1382 (
1383 	sal_uInt16 nSlot,				// die Id der auszufuehrenden Funktion
1384 	SfxCallMode eCall,			// SFX_CALLMODE_SYNCRHON, ..._ASYNCHRON oder ..._SLOT
1385 	const SfxItemSet &rArgs	    // <SfxItemSet> mit Parametern
1386 )
1387 
1388 /*  [Beschreibung]
1389 
1390 	Methode zum Ausf"uhren eines <SfxSlot>s "uber die Slot-Id.
1391 
1392 
1393 	[R"uckgabewert]
1394 
1395 	const SfxPoolItem*		Pointer auf ein bis zum n"achsten Durchlauf
1396 							der Message-Loop g"ultiges SfxPoolItem,
1397 							welches den R"uckgabewert enth"alt.
1398 
1399 							Oder ein 0-Pointer, wenn die Funktion nicht
1400 							ausgef"uhrt wurde (z.B. Abbruch durch den
1401 							Benutzer).
1402 */
1403 
1404 {
1405     return Execute( nSlot, eCall, 0, rArgs );
1406 }
1407 
1408 //--------------------------------------------------------------------
1409 const SfxPoolItem*  SfxDispatcher::Execute
1410 (
1411     sal_uInt16 nSlot,
1412     SfxCallMode eCall,
1413     sal_uInt16 nModi,
1414     const SfxItemSet &rArgs
1415 )
1416 {
1417 	if ( IsLocked(nSlot) )
1418 		return 0;
1419 
1420 	SfxShell *pShell = 0;
1421 	const SfxSlot *pSlot = 0;
1422 	if ( GetShellAndSlot_Impl( nSlot,  &pShell, &pSlot, sal_False,
1423 							   SFX_CALLMODE_MODAL==(eCall&SFX_CALLMODE_MODAL) ) )
1424 	{
1425 		SfxAllItemSet aSet( pShell->GetPool() );
1426 		SfxItemIter aIter(rArgs);
1427 		for ( const SfxPoolItem *pArg = aIter.FirstItem();
1428 			  pArg;
1429 			  pArg = aIter.NextItem() )
1430 			MappedPut_Impl( aSet, *pArg );
1431 		SfxRequest aReq( nSlot, eCall, aSet );
1432         aReq.SetModifier( nModi );
1433 		_Execute( *pShell, *pSlot, aReq, eCall );
1434 		return aReq.GetReturnValue();
1435 	}
1436 	return 0;
1437 }
1438 
1439 //--------------------------------------------------------------------
1440 const SfxPoolItem* SfxDispatcher::_Execute
1441 (
1442 	sal_uInt16				nSlot,		// die Id der auszufuehrenden Funktion
1443 	SfxCallMode 		eCall,		// SFX_CALLMODE_SYNCRHON, ..._ASYNCHRON oder ..._SLOT
1444 	va_list 			pVarArgs,	// Parameterliste ab 2. Parameter
1445 	const SfxPoolItem*	pArg1   	// erster Parameter
1446 )
1447 
1448 /*  [Beschreibung]
1449 
1450 	Methode zum Ausf"uhren eines <SfxSlot>s "uber die Slot-Id.
1451 
1452 
1453 	[R"uckgabewert]
1454 
1455 	const SfxPoolItem*		Pointer auf ein bis zum n"achsten Durchlauf
1456 							der Message-Loop g"ultiges SfxPoolItem,
1457 							welches den R"uckgabewert enth"alt.
1458 
1459 							Oder ein 0-Pointer, wenn die Funktion nicht
1460 							ausgef"uhrt wurde (z.B. Abbruch durch den
1461 							Benutzer).
1462 */
1463 
1464 {
1465 	if ( IsLocked(nSlot) )
1466 		return 0;
1467 
1468 	SfxShell *pShell = 0;
1469 	const SfxSlot *pSlot = 0;
1470 	if ( GetShellAndSlot_Impl( nSlot, &pShell, &pSlot, sal_False,
1471 							   SFX_CALLMODE_MODAL==(eCall&SFX_CALLMODE_MODAL) ) )
1472 	{
1473 	   SfxAllItemSet aSet( pShell->GetPool() );
1474 
1475 	   for ( const SfxPoolItem *pArg = pArg1;
1476 			 pArg;
1477 			 pArg = va_arg( pVarArgs, const SfxPoolItem* ) )
1478 		   MappedPut_Impl( aSet, *pArg );
1479 
1480 	   SfxRequest aReq( nSlot, eCall, aSet );
1481 	   _Execute( *pShell, *pSlot, aReq, eCall );
1482 	   return aReq.GetReturnValue();
1483 	}
1484 	return 0;
1485 }
1486 
1487 //--------------------------------------------------------------------
1488 const SfxPoolItem* SfxDispatcher::Execute
1489 (
1490 	sal_uInt16				nSlot,		// die Id der auszufuehrenden Funktion
1491 	SfxCallMode 		eCall,		// SFX_CALLMODE_SYNCRHON, ..._ASYNCHRON oder ..._SLOT
1492 	const SfxPoolItem*	pArg1,		// erster Parameter
1493 	... 							// 0-terminiertes Liste Parametern
1494 )
1495 
1496 /*  [Beschreibung]
1497 
1498 	Methode zum Ausf"uhren eines <SfxSlot>s "uber die Slot-Id.
1499 
1500 
1501 	[Anmerkung]
1502 
1503 	Die Parameter werden kopiert, k"onnen daher als Adresse von
1504 	Stack-Objekten "ubergeben werden.
1505 
1506 
1507 	[R"uckgabewert]
1508 
1509 	const SfxPoolItem*		Pointer auf ein bis zum n"achsten Durchlauf
1510 							der Message-Loop g"ultiges SfxPoolItem,
1511 							welches den R"uckgabewert enth"alt.
1512 
1513 							Oder ein 0-Pointer, wenn die Funktion nicht
1514 							ausgef"uhrt wurde (z.B. Abbruch durch den
1515 							Benutzer).
1516 
1517 
1518 	[Beispiel]
1519 
1520     pDispatcher->Execute( SID_OPENDOCUMENT, SFX_CALLMODE_SYNCHRON,
1521 		&SfxStringItem( SID_FILE_NAME, "\\tmp\\temp.sdd" ),
1522 		&SfxStringItem( SID_FILTER_NAME, "StarDraw Presentation" ),
1523 		&SfxBoolItem( SID_DOC_READONLY, sal_False ),
1524 		0L );
1525 */
1526 
1527 {
1528 	if ( IsLocked(nSlot) )
1529 		return 0;
1530 
1531 	SfxShell *pShell = 0;
1532 	const SfxSlot *pSlot = 0;
1533 	if ( GetShellAndSlot_Impl( nSlot, &pShell, &pSlot, sal_False,
1534 							   SFX_CALLMODE_MODAL==(eCall&SFX_CALLMODE_MODAL) ) )
1535 	{
1536 	   SfxAllItemSet aSet( pShell->GetPool() );
1537 
1538 	   va_list pVarArgs;
1539 	   va_start( pVarArgs, pArg1 );
1540 	   for ( const SfxPoolItem *pArg = pArg1;
1541 			 pArg;
1542 			 pArg = va_arg( pVarArgs, const SfxPoolItem* ) )
1543 		   MappedPut_Impl( aSet, *pArg );
1544 	   va_end(pVarArgs);
1545 
1546 	   SfxRequest aReq( nSlot, eCall, aSet );
1547 	   _Execute( *pShell, *pSlot, aReq, eCall );
1548 	   return aReq.GetReturnValue();
1549 	}
1550 	return 0;
1551 }
1552 
1553 //--------------------------------------------------------------------
1554 
1555 IMPL_LINK( SfxDispatcher, PostMsgHandler, SfxRequest*, pReq )
1556 
1557 /*	[Beschreibung]
1558 
1559 	Hilfsmethode zum Empfangen der asynchron auszuf"uhrenden <SfxRequest>s.
1560 */
1561 
1562 {
1563 	DBG_MEMTEST();
1564 	DBG_ASSERT( !pImp->bFlushing, "recursive call to dispatcher" );
1565 	SFX_STACK(SfxDispatcher::PostMsgHandler);
1566 
1567 	// ist auch der Pool noch nicht gestorben?
1568 //    SfxRequest* pReq = pExec->pRequest;
1569 	if ( !pReq->IsCancelled() )
1570 	{
1571 		if ( !IsLocked(pReq->GetSlot()) )
1572 		{
1573 			Flush();
1574             SfxSlotServer aSvr;
1575             if ( _FindServer(pReq->GetSlot(), aSvr, HACK(x) sal_True ) )
1576 //            SfxShell *pShell = GetShell(pExec->nLevel);
1577 //            if ( pShell && pShell->GetInterface()->GetSlot( pExec->pSlot->GetSlotId() ) )
1578 			{
1579                 const SfxSlot *pSlot = aSvr.GetSlot();
1580                 SfxShell *pSh = GetShell(aSvr.GetShellLevel());
1581 
1582 				DBG( SfxApplication *pSfxApp = SFX_APP() );
1583 				DBG( pSfxApp->EnterAsynchronCall_Impl() );
1584 
1585 				// Wenn pSlot ein "Pseudoslot" f"ur Macros oder Verben ist, kann
1586 				// er im Call_Impl zerst"ort werden, also nicht mehr benutzen!
1587 				pReq->SetSynchronCall( sal_False );
1588                 Call_Impl( *pSh, *pSlot, *pReq, pReq->AllowsRecording() ); //! woher bRecord?
1589 //                Call_Impl( *pShell, *pExec->pSlot, *pReq, sal_True ); //! woher bRecord?
1590 				DBG( pSfxApp->LeaveAsynchronCall_Impl() );
1591 			}
1592 
1593 //            delete pExec;
1594 		}
1595 		else
1596 		{
1597 //            pImp->xPoster->Post(pExec);
1598             if ( pImp->bLocked )
1599                 pImp->aReqArr.Insert( new SfxRequest(*pReq), pImp->aReqArr.Count() );
1600             else
1601                 pImp->xPoster->Post(new SfxRequest(*pReq));
1602 		}
1603 	}
1604 //    else
1605 //        delete pExec;
1606 
1607     delete pReq;
1608 	return 0;
1609 }
1610 //--------------------------------------------------------------------
1611 void SfxDispatcher::SetMenu_Impl()
1612 {
1613 	if ( pImp->pFrame )
1614 	{
1615         SfxViewFrame* pTop = pImp->pFrame->GetTopViewFrame();
1616         if ( pTop && pTop->GetBindings().GetDispatcher() == this )
1617         {
1618 			SfxFrame& rFrame = pTop->GetFrame();
1619             if ( rFrame.IsMenuBarOn_Impl() )
1620             {
1621                 com::sun::star::uno::Reference < com::sun::star::beans::XPropertySet > xPropSet( rFrame.GetFrameInterface(), com::sun::star::uno::UNO_QUERY );
1622                 if ( xPropSet.is() )
1623                 {
1624                     com::sun::star::uno::Reference< ::com::sun::star::frame::XLayoutManager > xLayoutManager;
1625                     com::sun::star::uno::Any aValue = xPropSet->getPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "LayoutManager" )));
1626                     aValue >>= xLayoutManager;
1627                     if ( xLayoutManager.is() )
1628                     {
1629                         rtl::OUString aMenuBarURL( RTL_CONSTASCII_USTRINGPARAM( "private:resource/menubar/menubar" ));
1630 						if ( !xLayoutManager->isElementVisible( aMenuBarURL ) )
1631                         	xLayoutManager->createElement( aMenuBarURL );
1632                     }
1633                 }
1634             }
1635         }
1636     }
1637 }
1638 
1639 //--------------------------------------------------------------------
1640 void SfxDispatcher::Update_Impl( sal_Bool bForce )
1641 {
1642 	SFX_STACK(SfxDispatcher::Update_Impl);
1643 
1644 	Flush();
1645 
1646     if ( !pImp->pFrame || pImp->bUILocked )
1647 		return;
1648 
1649 	SFX_APP();  // -Wall is this required???
1650 	SfxDispatcher *pDisp = this;
1651 	sal_Bool bUpdate = bForce;
1652     while ( pDisp && pDisp->pImp->pFrame )
1653 	{
1654         SfxWorkWindow *pWork = pDisp->pImp->pFrame->GetFrame().GetWorkWindow_Impl();
1655 		SfxDispatcher *pAct = pWork->GetBindings().GetDispatcher_Impl();
1656 		if ( pAct == pDisp || pAct == this )
1657 		{
1658 			if ( !bUpdate )
1659 				bUpdate = !pDisp->pImp->bUpdated;
1660 			pDisp->pImp->bUpdated = sal_True;
1661 		}
1662 		else
1663 			break;
1664 
1665 		pDisp = pDisp->pImp->pParent;
1666 	}
1667 
1668     if ( !bUpdate || pImp->pFrame->GetFrame().IsClosing_Impl() )
1669 		return;
1670 
1671     SfxViewFrame* pTop = pImp->pFrame ? pImp->pFrame->GetTopViewFrame() : NULL;
1672     sal_Bool bUIActive = pTop && pTop->GetBindings().GetDispatcher() == this;
1673 
1674     if ( !bUIActive && pTop && GetBindings() == &pTop->GetBindings() )
1675         // keep own tools internally for collecting
1676         GetBindings()->GetDispatcher()->pImp->bUpdated = sal_False;
1677 
1678     SfxBindings* pBindings = GetBindings();
1679     if ( pBindings )
1680         pBindings->DENTERREGISTRATIONS();
1681 
1682     com::sun::star::uno::Reference< com::sun::star::frame::XFrame > xFrame = pBindings->GetActiveFrame();
1683     com::sun::star::uno::Reference< com::sun::star::beans::XPropertySet > xPropSet( xFrame, com::sun::star::uno::UNO_QUERY );
1684     com::sun::star::uno::Reference< ::com::sun::star::frame::XLayoutManager > xLayoutManager;
1685     if ( xPropSet.is() )
1686     {
1687         try
1688         {
1689             com::sun::star::uno::Any aValue = xPropSet->getPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "LayoutManager" )) );
1690 	        aValue >>= xLayoutManager;
1691         }
1692         catch ( com::sun::star::uno::Exception& )
1693         {
1694         }
1695     }
1696 
1697     if ( xLayoutManager.is() )
1698         xLayoutManager->lock();
1699 
1700     sal_Bool bIsIPActive = pImp->pFrame && pImp->pFrame->GetObjectShell()->IsInPlaceActive();
1701     SfxInPlaceClient *pClient = pImp->pFrame ? pImp->pFrame->GetViewShell()->GetUIActiveClient() : NULL;
1702     if ( bUIActive && /* !bIsIPActive && */ ( !pClient || !pClient->IsObjectUIActive() ) )
1703 		SetMenu_Impl();
1704 
1705     SfxWorkWindow *pWorkWin = pImp->pFrame->GetFrame().GetWorkWindow_Impl();
1706     SfxWorkWindow *pTaskWin = pImp->pFrame->GetTopFrame().GetWorkWindow_Impl();
1707     pTaskWin->ResetStatusBar_Impl();
1708 
1709 	SfxDispatcher *pDispat = this;
1710 	while ( pDispat )
1711 	{
1712         SfxWorkWindow *pWork = pDispat->pImp->pFrame->GetFrame().GetWorkWindow_Impl();
1713 		SfxDispatcher *pAct = pWork->GetBindings().GetDispatcher_Impl();
1714 		if ( pAct == pDispat || pAct == this )
1715 		{
1716 			pWork->ResetObjectBars_Impl();
1717 			pWork->ResetChildWindows_Impl();
1718 		}
1719 
1720 		pDispat = pDispat->pImp->pParent;
1721 	}
1722 
1723 	sal_Bool bIsActive = sal_False;
1724 	SfxDispatcher *pActDispat = pWorkWin->GetBindings().GetDispatcher_Impl();
1725 	pDispat = this;
1726 	while ( pActDispat && !bIsActive )
1727 	{
1728 		if ( pDispat == pActDispat )
1729 			bIsActive = sal_True;
1730 		pActDispat = pActDispat->pImp->pParent;
1731 	}
1732 
1733     _Update_Impl( bUIActive, !bIsIPActive, bIsIPActive, pTaskWin );
1734 	if ( bUIActive || bIsActive )
1735 		pWorkWin->UpdateObjectBars_Impl();
1736 
1737     if ( pBindings )
1738         pBindings->DLEAVEREGISTRATIONS();
1739 
1740     if ( xLayoutManager.is() )
1741         xLayoutManager->unlock();
1742 
1743     return;
1744 }
1745 
1746 void SfxDispatcher::_Update_Impl( sal_Bool bUIActive, sal_Bool bIsMDIApp, sal_Bool bIsIPOwner, SfxWorkWindow *pTaskWin )
1747 {
1748 	SFX_APP();
1749     SfxWorkWindow *pWorkWin = pImp->pFrame->GetFrame().GetWorkWindow_Impl();
1750 	sal_Bool bIsActive = sal_False;
1751 	sal_Bool bIsTaskActive = sal_False;
1752 	SfxDispatcher *pActDispat = pWorkWin->GetBindings().GetDispatcher_Impl();
1753 	SfxDispatcher *pDispat = this;
1754 	while ( pActDispat && !bIsActive )
1755 	{
1756 		if ( pDispat == pActDispat )
1757 			bIsActive = sal_True;
1758 		pActDispat = pActDispat->pImp->pParent;
1759 	}
1760 
1761     if ( pImp->pParent && !pImp->bQuiet /* && bUIActive */ )
1762         pImp->pParent->_Update_Impl( bUIActive, bIsMDIApp, bIsIPOwner, pTaskWin );
1763 
1764 	for (sal_uInt16 n=0; n<SFX_OBJECTBAR_MAX; n++)
1765 		pImp->aObjBars[n].nResId = 0;
1766 	pImp->aChildWins.Remove(0, pImp->aChildWins.Count());
1767 
1768     // bQuiet : own shells aren't considered for UI and SlotServer
1769     // bNoUI: own Shells aren't considered fors UI
1770     if ( pImp->bQuiet || pImp->bNoUI || (pImp->pFrame && pImp->pFrame->GetObjectShell()->IsPreview()) )
1771 		return;
1772 
1773 	sal_uInt32 nStatBarId=0;
1774 	SfxShell *pStatusBarShell = NULL;
1775 
1776     SfxSlotPool* pSlotPool = &SfxSlotPool::GetSlotPool( GetFrame() );
1777 	sal_uInt16 nTotCount = pImp->aStack.Count();
1778 	for ( sal_uInt16 nShell = nTotCount; nShell > 0; --nShell )
1779 	{
1780 		SfxShell *pShell = GetShell( nShell-1 );
1781 		SfxInterface *pIFace = pShell->GetInterface();
1782 
1783         // don't consider shells if "Hidden" oder "Quiet"
1784 		sal_Bool bReadOnlyShell = IsReadOnlyShell_Impl( nShell-1 );
1785 		sal_uInt16 nNo;
1786 		for ( nNo = 0; pIFace && nNo<pIFace->GetObjectBarCount(); ++nNo )
1787 		{
1788 			sal_uInt16 nPos = pIFace->GetObjectBarPos(nNo);
1789 			if ( bReadOnlyShell && !( nPos & SFX_VISIBILITY_READONLYDOC ) )
1790 				continue;
1791 
1792             // check wether toolbar needs activation of a special feature
1793             sal_uInt32 nFeature = pIFace->GetObjectBarFeature(nNo);
1794 			if ( nFeature && !pShell->HasUIFeature( nFeature ) )
1795 				continue;
1796 
1797 			// check for toolboxes that are exclusively for a viewer
1798 			if ( pImp->pFrame)
1799 			{
1800 				sal_Bool bViewerTbx = SFX_VISIBILITY_VIEWER == ( nPos & SFX_VISIBILITY_VIEWER );
1801 				SfxObjectShell* pSh = pImp->pFrame->GetObjectShell();
1802 				SFX_ITEMSET_ARG( pSh->GetMedium()->GetItemSet(), pItem, SfxBoolItem, SID_VIEWONLY, sal_False );
1803 				sal_Bool bIsViewer = pItem && pItem->GetValue();
1804 				if ( bIsViewer != bViewerTbx )
1805 					continue;
1806 			}
1807 
1808             // always register toolbars, allows to switch them on
1809             sal_Bool bVisible = pIFace->IsObjectBarVisible(nNo);
1810 			if ( !bVisible )
1811 				nPos &= SFX_POSITION_MASK;
1812 
1813 			SfxObjectBars_Impl& rBar = pImp->aObjBars[nPos & SFX_POSITION_MASK];
1814 			rBar.nMode = nPos;
1815 			rBar.nResId = pIFace->GetObjectBarResId(nNo).GetId();
1816 			const String *pName = pIFace->GetObjectBarName(nNo);
1817 			if ( pName )
1818 				rBar.aName = *pName;
1819 			else
1820 				rBar.aName.Erase();
1821 			rBar.pIFace = pIFace;
1822 
1823 			if ( bUIActive || bIsActive )
1824 			{
1825 				pWorkWin->SetObjectBar_Impl(
1826 					nPos, rBar.nResId, rBar.pIFace, &rBar.aName );
1827 			}
1828 
1829 			if ( !bVisible )
1830 				rBar.nResId = 0;
1831 		}
1832 
1833 		for ( nNo=0; pIFace && nNo<pIFace->GetChildWindowCount(); nNo++ )
1834 		{
1835 			sal_uInt32 nId = pIFace->GetChildWindowId(nNo);
1836             const SfxSlot *pSlot = pSlotPool->GetSlot( (sal_uInt16) nId );
1837             DBG_ASSERT( pSlot, "Childwindow slot missing!");
1838 			if ( bReadOnlyShell )
1839 			{
1840                 // only show ChildWindows if their slot is allowed for readonly documents
1841                 if ( pSlot && !pSlot->IsMode( SFX_SLOT_READONLYDOC ) )
1842 					continue;
1843 			}
1844 
1845 			sal_uInt32 nFeature = pIFace->GetChildWindowFeature(nNo);
1846 			if ( nFeature && !pShell->HasUIFeature( nFeature ) )
1847 				continue;
1848 
1849             // slot decides wether a ChildWindow is shown when document is OLE server or OLE client
1850             sal_uInt16 nMode = SFX_VISIBILITY_STANDARD;
1851 			if( pSlot )
1852 			{
1853                 if ( pSlot->IsMode(SFX_SLOT_CONTAINER) )
1854 				{
1855                     if ( pWorkWin->IsVisible_Impl( SFX_VISIBILITY_CLIENT ) )
1856                         nMode |= SFX_VISIBILITY_CLIENT;
1857 				}
1858 				else
1859 				{
1860                     if ( pWorkWin->IsVisible_Impl( SFX_VISIBILITY_SERVER ) )
1861                         nMode |= SFX_VISIBILITY_SERVER;
1862 				}
1863 			}
1864 
1865 			if ( bUIActive || bIsActive )
1866 				pWorkWin->SetChildWindowVisible_Impl( nId, sal_True, nMode );
1867 			if ( bUIActive || bIsActive || !pWorkWin->IsFloating( (sal_uInt16) ( nId & 0xFFFF ) ) )
1868 				pImp->aChildWins.Insert( nId, pImp->aChildWins.Count());
1869 		}
1870 
1871 		if ( bIsMDIApp || bIsIPOwner )
1872 		{
1873 			sal_uInt32 nId = pIFace->GetStatusBarResId().GetId();
1874 			if ( nId )
1875 			{
1876 				nStatBarId = nId;
1877 				pStatusBarShell =  pShell;
1878 			}
1879 		}
1880 	}
1881 
1882 	for ( sal_uInt16 nPos=0; nPos<SFX_OBJECTBAR_MAX; nPos++ )
1883 	{
1884 		SfxObjectBars_Impl& rFixed = pImp->aFixedObjBars[nPos];
1885 		if ( rFixed.nResId )
1886 		{
1887 			SfxObjectBars_Impl& rBar = pImp->aObjBars[nPos];
1888 			rBar = rFixed;
1889 			pWorkWin->SetObjectBar_Impl( rFixed.nMode,
1890 				rFixed.nResId, rFixed.pIFace, &rFixed.aName );
1891 		}
1892 	}
1893 
1894 	if ( pTaskWin && ( bIsMDIApp || bIsIPOwner ) )
1895 	{
1896 		SfxDispatcher *pActDispatcher = pTaskWin->GetBindings().GetDispatcher_Impl();
1897 		SfxDispatcher *pDispatcher = this;
1898 		while ( pActDispatcher && !bIsTaskActive )
1899 		{
1900 			if ( pDispatcher == pActDispatcher )
1901 				bIsTaskActive = sal_True;
1902 			pActDispatcher = pActDispatcher->pImp->pParent;
1903 		}
1904 
1905         if ( bIsTaskActive && nStatBarId && pImp->pFrame )
1906 		{
1907             // internal frames also may control statusbar
1908             SfxBindings& rBindings = pImp->pFrame->GetBindings();
1909             pImp->pFrame->GetFrame().GetWorkWindow_Impl()->SetStatusBar_Impl( nStatBarId, pStatusBarShell, rBindings );
1910 		}
1911 	}
1912 }
1913 
1914 //--------------------------------------------------------------------
1915 void SfxDispatcher::FlushImpl()
1916 
1917 /*	[Beschreibung]
1918 
1919 	Hilfsmethode zum Ausf"uhren der ausstehenden Push- und Pop-Befehle.
1920 */
1921 
1922 {
1923 	DBG_PROFSTART(SfxDispatcherFlush);
1924 	DBG_MEMTEST();
1925 	SFX_STACK(SfxDispatcher::FlushImpl);
1926 
1927 	DBG_TRACE("Flushing dispatcher!");
1928 
1929 #ifdef DBG_UTIL
1930 	ByteString aMsg( "SfxDispatcher(" );
1931 	aMsg += ByteString::CreateFromInt64( (sal_uIntPtr) this );
1932 	aMsg += ")::Flush()";
1933 #endif
1934 
1935 	pImp->aTimer.Stop();
1936 
1937 	if ( pImp->pParent )
1938 		pImp->pParent->Flush();
1939 
1940 //	if ( pImp->bQuiet )
1941 //		return;
1942 
1943 	pImp->bFlushing = !pImp->bFlushing;
1944 	if ( !pImp->bFlushing )
1945 	{
1946 		pImp->bFlushing = sal_True;
1947 		DBG_PROFSTOP(SfxDispatcherFlush);
1948 //!
1949 #ifdef DBG_UTIL_MESSEHACK_AUSKOMMENT
1950 		DBG_ERROR( "reentering SfxDispatcher::Flush()" );
1951 		aMsg += " reentering, aborted";
1952 		DbgTrace( aMsg.GetBuffer() );
1953 #endif
1954 		return;
1955 	}
1956 
1957 	SfxApplication *pSfxApp = SFX_APP();
1958 
1959 	// in der 1. Runde den echten Stack 'um'bauen
1960 	SfxToDoStack_Impl aToDoCopy;
1961 	sal_Bool bModify = sal_False;
1962 	short nToDo;
1963 	for ( nToDo = pImp->aToDoStack.Count()-1; nToDo >= 0; --nToDo )
1964 	{
1965 		bModify = sal_True;
1966 
1967 		SfxToDo_Impl aToDo( pImp->aToDoStack.Top(nToDo) );
1968 		if ( aToDo.bPush )
1969 		{
1970 			// tats"aechlich pushen
1971 			DBG_ASSERT( !pImp->aStack.Contains( aToDo.pCluster ),
1972 						"pushed SfxShell already on stack" );
1973 			pImp->aStack.Push( aToDo.pCluster );
1974 			aToDo.pCluster->SetDisableFlags( pImp->nDisableFlags );
1975 
1976 			// die bewegte Shell merken
1977 			aToDoCopy.Push( aToDo );
1978 		}
1979 		else
1980 		{
1981 			// tats"aechlich poppen
1982 			SfxShell* pPopped = 0;
1983 			bool bFound = sal_False;
1984 			do
1985 			{
1986 				DBG_ASSERT( pImp->aStack.Count(), "popping from empty stack" );
1987 				pPopped = pImp->aStack.Pop();
1988 				pPopped->SetDisableFlags( 0 );
1989 				bFound = pPopped == aToDo.pCluster;
1990 
1991 				// die bewegte Shell merken
1992 				aToDoCopy.Push( SfxToDo_Impl( sal_False, aToDo.bDelete, sal_False, *pPopped) );
1993 			}
1994 			while ( aToDo.bUntil && !bFound );
1995 			DBG_ASSERT( bFound, "wrong SfxShell popped" );
1996 		}
1997 
1998 		if ( nToDo == 0 )
1999 			pImp->aToDoStack.Clear();
2000 	}
2001 
2002 	// ggf. Bindings invalidieren
2003 	if ( !pSfxApp->IsDowning() )
2004 	{
2005 		if ( bModify )
2006 		{
2007 			pImp->pCachedServ1 = 0;
2008 			pImp->pCachedServ2 = 0;
2009 		}
2010 
2011 		InvalidateBindings_Impl( bModify );
2012 	}
2013 
2014 	pImp->bFlushing = sal_False;
2015 	pImp->bUpdated = sal_False; // nicht nur bei bModify, falls Doc/Template-Config
2016 	bFlushed = sal_True;
2017 	DBG_TRACE("Successfully flushed dispatcher!");
2018 
2019 	// in der 2. Runde die Shells aktivieren und ggf. l"oschen
2020 	for ( nToDo = aToDoCopy.Count()-1; nToDo >= 0; --nToDo )
2021 	{
2022 		SfxToDo_Impl aToDo( aToDoCopy.Top(nToDo) );
2023 		if ( aToDo.bPush )
2024 		{
2025 			if ( pImp->bActive )
2026 				aToDo.pCluster->DoActivate_Impl(pImp->pFrame, sal_True);
2027 		}
2028 		else
2029 			if ( pImp->bActive )
2030 				aToDo.pCluster->DoDeactivate_Impl(pImp->pFrame, sal_True);
2031 	}
2032 	for ( nToDo = aToDoCopy.Count()-1; nToDo >= 0; --nToDo )
2033 	{
2034 		SfxToDo_Impl aToDo( aToDoCopy.Top(nToDo) );
2035 		if ( aToDo.bDelete ) delete aToDo.pCluster;
2036 	}
2037 	sal_Bool bAwakeBindings = aToDoCopy.Count() != 0;
2038 	if( bAwakeBindings )
2039 		aToDoCopy.Clear();
2040 
2041 	// Wenn bei Activate/Deactivate/Delete weitere Stackbewegungen erfolgt sind :
2042 	if (!bFlushed)
2043 		// falls jemand Push/Pop gerufen hat, wurde auch EnterReg gerufen!
2044 		FlushImpl();
2045 
2046     if( bAwakeBindings && GetBindings() )
2047 		GetBindings()->DLEAVEREGISTRATIONS();
2048 	DBG_PROFSTOP(SfxDispatcherFlush);
2049 
2050 	for (sal_uInt16 n=0; n<SFX_OBJECTBAR_MAX; n++)
2051 		pImp->aFixedObjBars[n].nResId = 0;
2052 
2053 #ifdef DBG_UTIL
2054 	aMsg += " done";
2055 	DbgTrace( aMsg.GetBuffer() );
2056 #endif
2057 }
2058 
2059 //--------------------------------------------------------------------
2060 void SfxDispatcher::SetSlotFilter
2061 (
2062 	HACK(hier muss mal ein enum rein)
2063 	sal_Bool 			bEnable,	/*	sal_True:
2064 									nur angegebene Slots enablen,
2065 									alle anderen disablen
2066 
2067 									sal_False:
2068 									die angegebenen Slots disablen,
2069 									alle anderen zun"achst enablen
2070 								*/
2071 	sal_uInt16 			nCount, 	// 	Anzahl der SIDs im folgenden Array
2072 	const sal_uInt16*	pSIDs		// 	sortiertes Array von 'nCount' SIDs
2073 )
2074 
2075 /*	[Beschreibung]
2076 
2077 	Mit dieser Methode wird ein Filter gesetzt, mit dem gezielt Slots
2078 	enabled bzw. disabled werden k"onnen. Das "ubergebene Array mu\s
2079 	bis zum Dtor bzw. n"achsten <SetSlotFilter()> erhalten bleiben, es
2080 	wird nicht vom Dispatcher gel"oscht, es kann daher static sein.
2081 
2082 	In ReadOnly-Dokumenten kann man mit 'bEnable==2' quasi das ReadOnlyDoc
2083 	Flag von Slots "ubersteuern, dieser werden also wieder gefunden. Auf
2084 	andere Slots hat das dann keine Auswirkung.
2085 
2086 
2087 	[Beispiel]
2088 
2089 	gezieltes disablen der Slots 1, 2 und 3:
2090 
2091 		static sal_uInt16 __READONLY_DATA pSIDs[] = { 1, 2, 3 };
2092 		pDisp->SetSlotFilter( sal_False, sizeof(pSIDs)/sizeof(sal_uInt16), pSIDs );
2093 
2094 	nur die Slots 5, 6 und 7 zulassen:
2095 
2096 		static sal_uInt16 __READONLY_DATA pSIDs[] = { 5, 6, 7 };
2097 		pDisp->SetSlotFilter( sal_True, sizeof(pSIDs)/sizeof(sal_uInt16), pSIDs );
2098 
2099 	Filter ausschalten:
2100 
2101 		pDisp->SetSlotFilter();
2102 */
2103 
2104 {
2105 #ifdef DBG_UTIL
2106 	// Array "uberpr"ufen
2107 	for ( sal_uInt16 n = 1; n < nCount; ++n )
2108 		DBG_ASSERT( pSIDs[n] > pSIDs[n-1], "SetSlotFilter: SIDs not sortet" );
2109 #endif
2110 
2111 	if ( pImp->pFilterSIDs )
2112 		pImp->pFilterSIDs = 0;
2113 
2114 	pImp->bFilterEnabling = bEnable;
2115 	pImp->nFilterCount = nCount;
2116 	pImp->pFilterSIDs = pSIDs;
2117 
2118 	GetBindings()->InvalidateAll(sal_True);
2119 }
2120 
2121 //--------------------------------------------------------------------
2122 EXTERN_C
2123 #if defined( PM2 ) && (!defined( CSET ) && !defined ( MTW ) && !defined( WTC ))
2124 int _stdcall
2125 #else
2126 #ifdef WNT
2127 int _cdecl
2128 #else
2129 int
2130 #endif
2131 #endif
2132 
2133 SfxCompareSIDs_Impl( const void* pSmaller, const void* pBigger )
2134 {
2135 	DBG_MEMTEST();
2136 	return ( (long) *((sal_uInt16*)pSmaller) ) - ( (long) *((sal_uInt16*)pBigger) );
2137 }
2138 
2139 //--------------------------------------------------------------------
2140 sal_Bool SfxDispatcher::IsSlotEnabledByFilter_Impl( sal_uInt16 nSID ) const
2141 
2142 /*	[Beschreibung]
2143 
2144 	Sucht 'nSID' in dem mit <SetSlotFilter()> gesetzten Filter und
2145 	liefert sal_True, falls die SID erlaubt ist, bzw. sal_False, falls sie
2146 	durch den Filter disabled ist.
2147 
2148 	[R"uckgabewert]
2149 	sal_Bool				0	=>	disabled
2150 						1	=> 	enabled
2151 						2	=>	enabled even if ReadOnlyDoc
2152 */
2153 
2154 {
2155 	// kein Filter?
2156 	if ( 0 == pImp->nFilterCount )
2157 		// => alle SIDs erlaubt
2158 		return sal_True;
2159 
2160 	// suchen
2161 	sal_Bool bFound = 0 != bsearch( &nSID, pImp->pFilterSIDs, pImp->nFilterCount,
2162 								sizeof(sal_uInt16), SfxCompareSIDs_Impl );
2163 
2164 	// even if ReadOnlyDoc
2165 	if ( 2 == pImp->bFilterEnabling )
2166 		return bFound ? 2 : 1;
2167 	// sonst je nach Negativ/Positiv Filter
2168 	return pImp->bFilterEnabling ? bFound : !bFound;
2169 }
2170 
2171 //--------------------------------------------------------------------
2172 sal_Bool SfxDispatcher::_TryIntercept_Impl
2173 (
2174 	sal_uInt16				nSlot,		// zu suchende Slot-Id
2175 	SfxSlotServer&	 	rServer,	// zu f"uellende <SfxSlotServer>-Instanz
2176 	sal_Bool				bSelf
2177 )
2178 {
2179 	// Eventuell geh"ort der parent auch zu einer Komponente
2180 	SfxDispatcher *pParent = pImp->pParent;
2181 	sal_uInt16 nLevels = pImp->aStack.Count();
2182 	while ( pParent && pParent->pImp->pFrame )
2183 	{
2184 		if ( pParent->pImp->pFrame->GetFrame().HasComponent() )
2185 		{
2186 			// Components d"urfen intercepten
2187 			if ( pParent->_TryIntercept_Impl( nSlot, rServer, sal_True ) )
2188 			{
2189 				// Die eigenen Shells zum Shelllevel hinzuz"ahlen
2190 				rServer.SetShellLevel( rServer.GetShellLevel() + nLevels );
2191 				return sal_True;
2192 			}
2193 			else
2194 				// Keine weitere Interception
2195 				break;
2196 		}
2197 		else
2198 			nLevels = nLevels + pParent->pImp->aStack.Count();
2199 
2200 		pParent = pParent->pImp->pParent;
2201 	}
2202 
2203 	if ( bSelf )
2204 	{
2205 		// Die ComponentViewShell befragen
2206 		Flush();
2207 		SfxShell *pObjShell = GetShell(0);
2208 		SfxInterface *pIFace = pObjShell->GetInterface();
2209 		const SfxSlot *pSlot = pIFace->GetSlot(nSlot);
2210 
2211 		if ( pSlot )
2212 		{
2213 			rServer.SetSlot(pSlot);
2214 			rServer.SetShellLevel(0);
2215 #ifdef DBG_UTILx
2216 			String aMsg( nSlot );
2217 			aMsg += " intercepted";
2218 			DbgTrace( aMsg.GetBuffer() );
2219 #endif
2220 			return sal_True;
2221 		}
2222 	}
2223 
2224 	return sal_False;
2225 }
2226 
2227 sal_Bool SfxDispatcher::_FindServer
2228 (
2229 	sal_uInt16				nSlot,		// zu suchende Slot-Id
2230 	SfxSlotServer&	 rServer,	 // zu f"uellnde <SfxSlotServer>-Instanz
2231 	sal_Bool				bModal		// trotz ModalMode
2232 )
2233 
2234 /*	[Beschreibung]
2235 
2236 	Diese Hilfsmethode sucht den <Slot-Server>, der nSlot zur Zeit bedient.
2237 	Als Ergebnis wird rServer entsprechend gef"ullt.
2238 
2239 	Falls bekannt, kann das SfxInterface mitgegeben werden, von welchem
2240 	nSlot momentan bedient wird.
2241 
2242 	Vor der Suche nach nSlot wird der SfxDispatcher geflusht.
2243 
2244 
2245 	[R"uckgabewert]
2246 
2247 	sal_Bool				sal_True
2248 						Der Slot wurde gefunden, rServer ist g"ultig.
2249 
2250 						sal_False
2251 						Der Slot wird momentan nicht bedient, rServer
2252 						ist ung"ultig.
2253 */
2254 
2255 {
2256 	SFX_STACK(SfxDispatcher::_FindServer);
2257 
2258 	// Dispatcher gelockt? (SID_HELP_PI trotzdem durchlassen)
2259 	if ( IsLocked(nSlot) )
2260 	{
2261 		pImp->bInvalidateOnUnlock = sal_True;
2262 		return sal_False;
2263 	}
2264 
2265 	// Anzahl der Shells auf den verkettenten Dispatchern z"ahlen
2266 	Flush();
2267 	sal_uInt16 nTotCount = pImp->aStack.Count();
2268 	if ( pImp->pParent )
2269 	{
2270 		SfxDispatcher *pParent = pImp->pParent;
2271 		while ( pParent )
2272 		{
2273 			nTotCount = nTotCount + pParent->pImp->aStack.Count();
2274 			pParent = pParent->pImp->pParent;
2275 		}
2276 	}
2277 
2278 	// Verb-Slot?
2279 	if (nSlot >= SID_VERB_START && nSlot <= SID_VERB_END)
2280 	{
2281 		for ( sal_uInt16 nShell = 0;; ++nShell )
2282 		{
2283             SfxShell *pSh = GetShell(nShell);
2284             if ( pSh == NULL )
2285                 return false;
2286 			if ( pSh->ISA(SfxViewShell) )
2287 			{
2288                 const SfxSlot* pSlot = pSh->GetVerbSlot_Impl(nSlot);
2289                 if ( pSlot )
2290                 {
2291                     rServer.SetShellLevel(nShell);
2292                     rServer.SetSlot( pSlot );
2293                     return true;
2294                 }
2295 			}
2296 		}
2297 	}
2298 
2299 	// SID gegen gesetzten Filter pr"ufen
2300 	sal_uInt16 nSlotEnableMode=0;
2301 	if ( pImp->pFrame )
2302 	{
2303 		nSlotEnableMode = IsSlotEnabledByFilter_Impl( nSlot );
2304 		if ( 0 == nSlotEnableMode )
2305 			return sal_False;
2306 	}
2307 
2308 	// im Quiet-Mode nur Parent-Dispatcher
2309 	if ( pImp->bQuiet )
2310 	{
2311 		if ( pImp->pParent )
2312 		{
2313 			sal_Bool bRet = pImp->pParent->_FindServer( nSlot, rServer, bModal );
2314 			rServer.SetShellLevel
2315 				( rServer.GetShellLevel() + pImp->aStack.Count() );
2316 			return bRet;
2317 		}
2318 		else
2319 			return sal_False;
2320 	}
2321 
2322 	sal_Bool bReadOnly = ( 2 != nSlotEnableMode && pImp->bReadOnly );
2323 //				( pImp->pFrame && pImp->pFrame->GetObjectShell() );
2324 //				  pImp->pFrame->GetObjectShell()->IsLoading() );
2325 
2326 	// durch alle Shells der verketteten Dispatchern von oben nach unten suchen
2327 #ifdef DBG_UTILx
2328 	String aStack( "Stack:" );
2329 #endif
2330 	sal_uInt16 nFirstShell = pImp->bModal && !bModal ? pImp->aStack.Count() : 0;
2331 	for ( sal_uInt16 i = nFirstShell; i < nTotCount; ++i )
2332 	{
2333 		SfxShell *pObjShell = GetShell(i);
2334 		SfxInterface *pIFace = pObjShell->GetInterface();
2335 		const SfxSlot *pSlot = pIFace->GetSlot(nSlot);
2336 
2337 		if ( pSlot && pSlot->nDisableFlags && ( pSlot->nDisableFlags & pObjShell->GetDisableFlags() ) != 0 )
2338 			return sal_False;
2339 
2340 		if ( pSlot && !( pSlot->nFlags & SFX_SLOT_READONLYDOC ) && bReadOnly )
2341 			return sal_False;
2342 
2343 		if ( pSlot )
2344 		{
2345 			// Slot geh"ort zum Container?
2346 			bool bIsContainerSlot = pSlot->IsMode(SFX_SLOT_CONTAINER);
2347             bool bIsInPlace = pImp->pFrame && pImp->pFrame->GetObjectShell()->IsInPlaceActive();
2348 
2349 			// Shell geh"ort zum Server?
2350 			// AppDispatcher oder IPFrame-Dispatcher
2351 			bool bIsServerShell = !pImp->pFrame || bIsInPlace;
2352 
2353 			// Nat"urlich sind ServerShell-Slots auch ausf"uhrbar, wenn sie auf
2354 			// einem Container-Dispatcher ohne IPClient ausgef"uhrt werden sollen.
2355 			if ( !bIsServerShell )
2356 			{
2357 				SfxViewShell *pViewSh = pImp->pFrame->GetViewShell();
2358                 bIsServerShell = !pViewSh || !pViewSh->GetUIActiveClient();
2359 			}
2360 
2361 			// Shell geh"ort zum Container?
2362 			// AppDispatcher oder kein IPFrameDispatcher
2363 			bool bIsContainerShell = !pImp->pFrame || !bIsInPlace;
2364 			// Shell und Slot passen zusammen
2365 			if ( !( ( bIsContainerSlot && bIsContainerShell ) ||
2366 					( !bIsContainerSlot && bIsServerShell ) ) )
2367 				pSlot = 0;
2368 		}
2369 
2370 #ifdef DBG_UTILx
2371 		if ( pSlot )
2372 		{
2373 			String aMsg( nSlot );
2374 			aMsg += " found in ";
2375 			aMsg += pObjShell->GetInterface()->GetClassName();
2376 			DbgTrace( aMsg.GetBuffer() );
2377 		}
2378 		else
2379 		{
2380 			aStack += " ";
2381 			aStack += pObjShell->GetInterface()->GetClassName();
2382 		}
2383 #endif
2384 		if ( pSlot && !IsAllowed( nSlot ) )
2385 		{
2386 			pSlot = NULL;
2387 		}
2388 
2389 		if ( pSlot )
2390 		{
2391 			rServer.SetSlot(pSlot);
2392 			rServer.SetShellLevel(i);
2393 			return sal_True;
2394 		}
2395 	}
2396 
2397 #ifdef DBG_UTILx
2398 	String aMsg( nSlot );
2399 	aMsg += " not found in ";
2400 	aMsg += aStack;
2401 	DbgTrace( aMsg.GetBuffer() );
2402 #endif
2403 	return sal_False;
2404 }
2405 
2406 sal_Bool SfxDispatcher::HasSlot_Impl( sal_uInt16 nSlot )
2407 {
2408 	Flush();
2409 	sal_uInt16 nTotCount = pImp->aStack.Count();
2410 
2411     if ( pImp->pParent && !pImp->pParent->pImp->pFrame )
2412     {
2413         // the last frame also uses the AppDispatcher
2414         nTotCount = nTotCount + pImp->aStack.Count();
2415     }
2416 
2417 	if (nSlot >= SID_VERB_START && nSlot <= SID_VERB_END)
2418 	{
2419         // Verb-Slot?
2420 		for ( sal_uInt16 nShell = 0;; ++nShell )
2421 		{
2422             SfxShell *pSh = GetShell(nShell);
2423             if ( pSh == NULL )
2424                 return false;
2425 			if ( pSh->ISA(SfxViewShell) )
2426 				return true;
2427 		}
2428 	}
2429 
2430 	// SID gegen gesetzten Filter pr"ufen
2431 	sal_uInt16 nSlotEnableMode=0;
2432 	if ( pImp->pFrame )
2433 	{
2434 		nSlotEnableMode = IsSlotEnabledByFilter_Impl( nSlot );
2435 		if ( 0 == nSlotEnableMode )
2436 			return sal_False;
2437 	}
2438 
2439 	// im Quiet-Mode nur Parent-Dispatcher
2440 	if ( pImp->bQuiet )
2441 		return sal_False;
2442 
2443 	sal_Bool bReadOnly = ( 2 != nSlotEnableMode && pImp->bReadOnly );
2444 //				( pImp->pFrame && pImp->pFrame->GetObjectShell());
2445 //				  pImp->pFrame->GetObjectShell()->IsLoading() );
2446 
2447 	for ( sal_uInt16 i=0 ; i < nTotCount; ++i )
2448 	{
2449 		SfxShell *pObjShell = GetShell(i);
2450 		SfxInterface *pIFace = pObjShell->GetInterface();
2451 		const SfxSlot *pSlot = pIFace->GetSlot(nSlot);
2452 		if ( pSlot && pSlot->nDisableFlags && ( pSlot->nDisableFlags & pObjShell->GetDisableFlags() ) != 0 )
2453 			return sal_False;
2454 
2455 		if ( pSlot && !( pSlot->nFlags & SFX_SLOT_READONLYDOC ) && bReadOnly )
2456 			return sal_False;
2457 
2458 		if ( pSlot )
2459 		{
2460 			// Slot geh"ort zum Container?
2461 			bool bIsContainerSlot = pSlot->IsMode(SFX_SLOT_CONTAINER);
2462             bool bIsInPlace = pImp->pFrame && pImp->pFrame->GetObjectShell()->IsInPlaceActive();
2463 
2464             // Shell geh"ort zum Server?
2465 			// AppDispatcher oder IPFrame-Dispatcher
2466 			bool bIsServerShell = !pImp->pFrame || bIsInPlace;
2467 
2468 			// Nat"urlich sind ServerShell-Slots auch ausf"uhrbar, wenn sie auf
2469 			// einem Container-Dispatcher ohne IPClient ausgef"uhrt werden sollen.
2470 			if ( !bIsServerShell )
2471 			{
2472 				SfxViewShell *pViewSh = pImp->pFrame->GetViewShell();
2473                 bIsServerShell = !pViewSh || !pViewSh->GetUIActiveClient();
2474 			}
2475 
2476 			// Shell geh"ort zum Container?
2477 			// AppDispatcher oder kein IPFrameDispatcher
2478 			bool bIsContainerShell = !pImp->pFrame || !bIsInPlace;
2479 
2480 			// Shell und Slot passen zusammen
2481 			if ( !( ( bIsContainerSlot && bIsContainerShell ) ||
2482 					( !bIsContainerSlot && bIsServerShell ) ) )
2483 				pSlot = 0;
2484 		}
2485 
2486 		if ( pSlot && !IsAllowed( nSlot ) )
2487 			pSlot = NULL;
2488 
2489 		if ( pSlot )
2490 			return sal_True;
2491 	}
2492 
2493 	return sal_False;
2494 }
2495 
2496 
2497 
2498 //--------------------------------------------------------------------
2499 sal_Bool SfxDispatcher::_FillState
2500 (
2501 	const SfxSlotServer& rSvr,		 // abzufragende <Slot-Server>
2502 	SfxItemSet& 			rState, 	// zu f"ullendes <SfxItemSet>
2503 	const SfxSlot*			pRealSlot	// ggf. der tats"achliche Slot
2504 )
2505 
2506 /*	[Beschreibung]
2507 
2508 	Hilfsmethode zum Abfragen des Status des <Slot-Server>s rSvr.
2509 	In rState m"ussen die gew"unschten Slots-Ids (teilweise in Which-Ids
2510 	des betreffenden Pools umgewandelt) vorhanden sein.
2511 
2512 	Der SfxDispatcher wird vor der Abfrage geflusht.
2513 */
2514 
2515 {
2516 	SFX_STACK(SfxDispatcher::_FillState);
2517 
2518 	DBG_PROFSTART(SfxDispatcherFillState);
2519 
2520 	const SfxSlot *pSlot = rSvr.GetSlot();
2521 	if ( pSlot && IsLocked( pSlot->GetSlotId() ) )
2522 	{
2523 		pImp->bInvalidateOnUnlock = sal_True;
2524 		DBG_PROFSTOP(SfxDispatcherFillState);
2525 		return sal_False;
2526 	}
2527 
2528 	if ( pSlot )
2529 	{
2530 		DBG_ASSERT(bFlushed, "Dispatcher not flushed after retrieving slot servers!");
2531         if ( !bFlushed )
2532             return sal_False;
2533 		// Flush();
2534 
2535 		// Objekt ermitteln und Message an diesem Objekt aufrufen
2536 		SfxShell *pSh = GetShell(rSvr.GetShellLevel());
2537 		DBG_ASSERT(pSh, "ObjektShell nicht gefunden");
2538 
2539 		SfxStateFunc pFunc;
2540 
2541 		if (pRealSlot)
2542 			pFunc = pRealSlot->GetStateFnc();
2543 		else
2544 			pFunc = pSlot->GetStateFnc();
2545 
2546 		pSh->CallState( pFunc, rState );
2547 #ifdef DBG_UTIL
2548 		// pr"ufen, ob IDL (SlotMap) und aktuelle Items "ubereinstimmen
2549 		if ( DbgIsAssertWarning() && rState.Count() )
2550 		{
2551 			SfxInterface *pIF = pSh->GetInterface();
2552 			SfxItemIter aIter( rState );
2553 			for ( const SfxPoolItem *pItem = aIter.FirstItem();
2554 				  pItem;
2555 				  pItem = aIter.NextItem() )
2556 				if ( !IsInvalidItem(pItem) && !pItem->ISA(SfxVoidItem) )
2557 				{
2558 					sal_uInt16 nSlotId = rState.GetPool()->GetSlotId(pItem->Which());
2559 					if ( !pItem->IsA(pIF->GetSlot(nSlotId)->GetType()->Type()) )
2560 					{
2561 						ByteString aMsg( "item-type unequal to IDL (=> no BASIC)" );
2562 						aMsg += "\nwith SID: ";
2563 						aMsg += ByteString::CreateFromInt32( nSlotId );
2564 						aMsg += "\nin ";
2565 						aMsg += pIF->GetClassName();
2566 						DbgOut( aMsg.GetBuffer(), DBG_OUT_ERROR, __FILE__, __LINE__);
2567 					}
2568 				}
2569 		}
2570 #endif
2571 
2572 		DBG_PROFSTOP(SfxDispatcherFillState);
2573 		return sal_True;
2574 	}
2575 
2576 	DBG_PROFSTOP(SfxDispatcherFillState);
2577 	return sal_False;
2578 }
2579 
2580 //--------------------------------------------------------------------
2581 const SfxPoolItem* SfxDispatcher::_Execute( const SfxSlotServer &rSvr )
2582 
2583 /*  [Beschreibung]
2584 
2585 	Diese Methode f"uhrt einen Request "uber einen gecachten <Slot-Server>
2586 	aus.
2587 */
2588 
2589 {
2590 	const SfxSlot *pSlot = rSvr.GetSlot();
2591 	if ( IsLocked( pSlot->GetSlotId() ) )
2592 		return 0;
2593 
2594 	if ( pSlot )
2595 	{
2596 		Flush();
2597 
2598 		if ( pSlot->IsMode(SFX_SLOT_ASYNCHRON) )
2599 			//! ignoriert rSvr
2600 		{
2601 			SfxShell *pShell = GetShell( rSvr.GetShellLevel() );
2602 			SfxDispatcher *pDispat = this;
2603 			while ( pDispat )
2604 			{
2605 				sal_uInt16 nShellCount = pDispat->pImp->aStack.Count();
2606 				for ( sal_uInt16 n=0; n<nShellCount; n++ )
2607 					if ( pShell == pDispat->pImp->aStack.Top(n) )
2608 					{
2609                         pDispat->pImp->xPoster->Post(
2610                             new SfxRequest( pSlot->GetSlotId(),
2611                                 SFX_CALLMODE_RECORD, pShell->GetPool() ) );
2612 //                        pDispat->pImp->xPoster->Post(new Executer(
2613 //                                new SfxRequest( pSlot->GetSlotId(),
2614 //                                    SFX_CALLMODE_RECORD, pShell->GetPool() ),
2615 //                                pSlot, n ));
2616 						return 0;
2617 					}
2618 			}
2619 		}
2620 		else
2621 		{
2622 			// Objekt ermitteln und Message an diesem Objekt aufrufen
2623 			SfxShell *pSh = GetShell(rSvr.GetShellLevel());
2624 			SfxRequest aReq( pSlot->GetSlotId(), SFX_CALLMODE_RECORD, pSh->GetPool() );
2625 			if ( Call_Impl( *pSh, *pSlot, aReq, sal_True ) ) // von Bindings immer recorden
2626 				return aReq.GetReturnValue();
2627 		}
2628 	}
2629 	return 0;
2630 }
2631 
2632 //----------------------------------------------------------------------
2633 void SfxDispatcher::ExecutePopup( sal_uInt16 nConfigId,
2634 								  Window *pWin, const Point *pPos,
2635 								  const SfxPoolItem *, ... )
2636 {
2637     ExecutePopup( nConfigId, pWin, pPos );
2638 }
2639 
2640 SfxPopupMenuManager* SfxDispatcher::Popup( sal_uInt16 nConfigId,Window *pWin, const Point *pPos )
2641 {
2642 	SfxDispatcher &rDisp = *SFX_APP()->GetDispatcher_Impl();
2643 	sal_uInt16 nShLevel = 0;
2644 	SfxShell *pSh;
2645 	nShLevel=0;
2646 
2647 	if ( rDisp.pImp->bQuiet )
2648 	{
2649 		nConfigId = 0;
2650 		nShLevel = rDisp.pImp->aStack.Count();
2651 	}
2652 
2653 	Window *pWindow = pWin ? pWin : rDisp.pImp->pFrame->GetFrame().GetWorkWindow_Impl()->GetWindow();
2654     for ( pSh = rDisp.GetShell(nShLevel); pSh; ++nShLevel, pSh = rDisp.GetShell(nShLevel) )
2655 	{
2656 		const ResId& rResId = pSh->GetInterface()->GetPopupMenuResId();
2657         if ( ( nConfigId == 0 && rResId.GetId() ) || ( nConfigId != 0 && rResId.GetId() == nConfigId ) )
2658 		{
2659                 return SfxPopupMenuManager::Popup( rResId, rDisp.GetFrame(), pPos ? *pPos : pWindow->GetPointerPosPixel(), pWindow );
2660 		}
2661 	}
2662 	return 0;
2663 }
2664 
2665 
2666 //----------------------------------------------------------------------
2667 void SfxDispatcher::ExecutePopup( sal_uInt16 nConfigId, Window *pWin, const Point *pPos )
2668 {
2669     SfxDispatcher &rDisp = *SFX_APP()->GetDispatcher_Impl();
2670 	sal_uInt16 nShLevel = 0;
2671 	SfxShell *pSh;
2672 /*
2673 	const SvVerbList *pVerbList = 0;
2674 	sal_uInt16 nMaxShellLevel = rDisp.pImp->aStack.Count();
2675 	for ( pSh = rDisp.GetShell(nShLevel);
2676 		  pSh && nShLevel < nMaxShellLevel ;
2677 		  ++nShLevel, pSh = rDisp.GetShell(nShLevel) )
2678 	{
2679         if ( pSh->GetVerbs() )
2680 		{
2681 			pVerbList = pSh->GetVerbs();
2682 			break;
2683 		}
2684     }
2685 */
2686 	nShLevel=0;
2687 	if ( rDisp.pImp->bQuiet )
2688 	{
2689 		nConfigId = 0;
2690 		nShLevel = rDisp.pImp->aStack.Count();
2691 	}
2692 
2693     Window *pWindow = pWin ? pWin : rDisp.pImp->pFrame->GetFrame().GetWorkWindow_Impl()->GetWindow();
2694     for ( pSh = rDisp.GetShell(nShLevel); pSh; ++nShLevel, pSh = rDisp.GetShell(nShLevel) )
2695 	{
2696 		const ResId& rResId = pSh->GetInterface()->GetPopupMenuResId();
2697         if ( ( nConfigId == 0 && rResId.GetId() ) || ( nConfigId != 0 && rResId.GetId() == nConfigId ) )
2698 		{
2699             //SfxPopupMenuManager aPop( rResId.GetId(), *rDisp.GetBindings() );
2700             //aPop.SetResMgr(rResId.GetResMgr());
2701             //aPop.AddClipboardFunctions();
2702             //aPop.Initialize();
2703             //if ( pVerbList && pVerbList->Count() )
2704             //    aPop.InsertVerbs(pVerbList);
2705             //aPop.RemoveDisabledEntries();
2706             //aPop.Execute( pPos ? *pPos : pWindow->GetPointerPosPixel(), pWindow );
2707             SfxPopupMenuManager::ExecutePopup( rResId, rDisp.GetFrame(), pPos ? *pPos : pWindow->GetPointerPosPixel(), pWindow );
2708 			return;
2709 		}
2710 	}
2711 }
2712 
2713 //----------------------------------------------------------------------
2714 void SfxDispatcher::ExecutePopup( const ResId &rId, Window *pWin, const Point *pPos )
2715 {
2716     Window *pWindow = pWin ? pWin : pImp->pFrame->GetFrame().GetWorkWindow_Impl()->GetWindow();
2717 /*
2718 	SfxPopupMenuManager aPop( rId, *GetBindings() );
2719 	aPop.AddClipboardFunctions();
2720 	aPop.Initialize();
2721 	aPop.RemoveDisabledEntries();
2722     aPop.Execute( pPos ? *pPos : pWindow->GetPointerPosPixel(), pWindow );
2723 */
2724     SfxPopupMenuManager::ExecutePopup( rId, GetFrame(), pPos ? *pPos : pWindow->GetPointerPosPixel(), pWindow );
2725 }
2726 
2727 //--------------------------------------------------------------------
2728 void SfxDispatcher::Lock( sal_Bool bLock )
2729 
2730 /*  [Beschreibung]
2731 
2732 	Mit dieser Methode kann der SfxDispatcher gesperrt und freigegeben
2733 	werden. Ein gesperrter SfxDispatcher f"uhrt keine <SfxRequest>s mehr
2734 	aus und liefert keine Status-Informationen mehr. Er verh"alt sich
2735 	so als w"aren alle Slots disabled.
2736 */
2737 
2738 {
2739     SfxBindings* pBindings = GetBindings();
2740 	if ( !bLock && pImp->bLocked && pImp->bInvalidateOnUnlock )
2741 	{
2742         if ( pBindings )
2743             pBindings->InvalidateAll(sal_True);
2744 		pImp->bInvalidateOnUnlock = sal_False;
2745 	}
2746     else if ( pBindings )
2747         pBindings->InvalidateAll(sal_False);
2748 	pImp->bLocked = bLock;
2749     if ( !bLock )
2750     {
2751         sal_uInt16 nCount = pImp->aReqArr.Count();
2752         for ( sal_uInt16 i=0; i<nCount; i++ )
2753             pImp->xPoster->Post( pImp->aReqArr[i] );
2754         pImp->aReqArr.Remove( 0, nCount );
2755     }
2756 }
2757 
2758 sal_uInt32 SfxDispatcher::GetObjectBarId( sal_uInt16 nPos ) const
2759 {
2760 	return pImp->aObjBars[nPos].nResId;
2761 }
2762 
2763 //--------------------------------------------------------------------
2764 void SfxDispatcher::ResetObjectBars_Impl()
2765 
2766 /*  [Beschreibung]
2767 
2768 	Mit dieser Methode werden alle Objectbar-Anforderungen, die dieser
2769 	Dispatcher an das AppWindow hat, beseitigt.
2770 */
2771 {
2772 	for (sal_uInt16 n=0; n<SFX_OBJECTBAR_MAX; n++)
2773 		pImp->aObjBars[n].nResId = 0;
2774 	pImp->aChildWins.Remove(0, pImp->aChildWins.Count());
2775 }
2776 
2777 
2778 //--------------------------------------------------------------------
2779 void SfxDispatcher::DebugOutput_Impl() const
2780 {
2781 #ifdef DBG_UTIL
2782 
2783 	sal_uInt16 nOld = (sal_uInt16) DbgGetData()->nTraceOut;
2784 	DbgGetData()->nTraceOut = DBG_OUT_FILE;
2785 
2786 	if (bFlushed)
2787 		DBG_TRACE("Flushed");
2788 	if (pImp->bUpdated)
2789 		DBG_TRACE("Updated");
2790 
2791 	for ( sal_uInt16 nShell = pImp->aStack.Count(); nShell > 0; --nShell )
2792 	{
2793 		SfxShell *pShell = GetShell(nShell-1);
2794 		const SfxInterface *pIFace = pShell->GetInterface();
2795 		DBG_TRACE (pIFace->GetClassName());
2796 	}
2797 
2798 	DbgGetData()->nTraceOut = nOld;
2799 
2800 #endif
2801 }
2802 
2803 void SfxDispatcher::LockUI_Impl( sal_Bool bLock )
2804 {
2805 	sal_Bool bWasLocked = pImp->bUILocked;
2806 	pImp->bUILocked = bLock;
2807 	if ( !bLock && bWasLocked )
2808 		Update_Impl( sal_True );
2809 }
2810 
2811 //-------------------------------------------------------------------------
2812 void SfxDispatcher::HideUI( sal_Bool bHide )
2813 {
2814 //	if ( !bHide && pImp->bReadOnly )
2815 //		bHide = sal_True;
2816 	sal_Bool bWasHidden = pImp->bNoUI;
2817 	pImp->bNoUI = bHide;
2818 	if ( pImp->pFrame )
2819 	{
2820         SfxViewFrame* pTop = pImp->pFrame->GetTopViewFrame();
2821         if ( pTop && pTop->GetBindings().GetDispatcher() == this )
2822         {
2823 			SfxFrame& rFrame = pTop->GetFrame();
2824             if ( rFrame.IsMenuBarOn_Impl() )
2825             {
2826                 com::sun::star::uno::Reference < com::sun::star::beans::XPropertySet > xPropSet( rFrame.GetFrameInterface(), com::sun::star::uno::UNO_QUERY );
2827                 if ( xPropSet.is() )
2828                 {
2829                     com::sun::star::uno::Reference< ::com::sun::star::frame::XLayoutManager > xLayoutManager;
2830                     com::sun::star::uno::Any aValue = xPropSet->getPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "LayoutManager" )));
2831                     aValue >>= xLayoutManager;
2832                     if ( xLayoutManager.is() )
2833                         xLayoutManager->setVisible( !bHide );
2834                 }
2835             }
2836         }
2837     }
2838 
2839 	if ( bHide != bWasHidden )
2840 		Update_Impl( sal_True );
2841 }
2842 
2843 void SfxDispatcher::SetReadOnly_Impl( sal_Bool bOn )
2844 {
2845 	pImp->bReadOnly = bOn;
2846 //	pImp->bNoUI = bOn;
2847 }
2848 
2849 sal_Bool SfxDispatcher::GetReadOnly_Impl() const
2850 {
2851 	return pImp->bReadOnly;
2852 }
2853 
2854 //-------------------------------------------------------------------------
2855 void SfxDispatcher::SetQuietMode_Impl( sal_Bool bOn )
2856 
2857 /*	[Beschreibung]
2858 
2859 	Bei 'bOn' stellt sich dieser Dispatcher quasi tot und leitet alles
2860 	an den Parent-Dispatcher weiter.
2861 */
2862 
2863 {
2864 	pImp->bQuiet = bOn;
2865     SfxBindings* pBindings = GetBindings();
2866     if ( pBindings )
2867         pBindings->InvalidateAll(sal_True);
2868 }
2869 
2870 //-------------------------------------------------------------------------
2871 void SfxDispatcher::SetModalMode_Impl( sal_Bool bOn )
2872 
2873 /*	[Beschreibung]
2874 
2875 	Bei 'bOn' werden nur noch Slots des Parent-Dispatchers gefunden.
2876 */
2877 
2878 {
2879 	pImp->bModal = bOn;
2880     SfxBindings* pBindings = GetBindings();
2881     if ( pBindings )
2882         pBindings->InvalidateAll(sal_True);
2883 }
2884 
2885 void SfxDispatcher::SetExecuteMode( sal_uInt16 nMode )
2886 {
2887 	pImp->nStandardMode = nMode;
2888 }
2889 
2890 SfxItemState SfxDispatcher::QueryState( sal_uInt16 nSlot, const SfxPoolItem* &rpState )
2891 {
2892 	SfxShell *pShell = 0;
2893 	const SfxSlot *pSlot = 0;
2894 	if ( GetShellAndSlot_Impl( nSlot, &pShell, &pSlot, sal_False, sal_False ) )
2895 	{
2896 		rpState = pShell->GetSlotState(nSlot);
2897 		if ( !rpState )
2898 			return SFX_ITEM_DISABLED;
2899 		else
2900 			return SFX_ITEM_AVAILABLE;
2901 	}
2902 
2903 	return SFX_ITEM_DISABLED;
2904 }
2905 
2906 SfxItemState SfxDispatcher::QueryState( sal_uInt16 nSID, ::com::sun::star::uno::Any& rAny )
2907 {
2908 	SfxShell *pShell = 0;
2909 	const SfxSlot *pSlot = 0;
2910 	if ( GetShellAndSlot_Impl( nSID, &pShell, &pSlot, sal_False, sal_False ) )
2911 	{
2912         const SfxPoolItem* pItem( 0 );
2913 
2914         pItem = pShell->GetSlotState( nSID );
2915 		if ( !pItem )
2916 			return SFX_ITEM_DISABLED;
2917         else
2918         {
2919             ::com::sun::star::uno::Any aState;
2920             if ( !pItem->ISA(SfxVoidItem) )
2921             {
2922                 sal_uInt16 nSubId( 0 );
2923                 SfxItemPool& rPool = pShell->GetPool();
2924                 sal_uInt16 nWhich = rPool.GetWhich( nSID );
2925                 if ( rPool.GetMetric( nWhich ) == SFX_MAPUNIT_TWIP )
2926                     nSubId |= CONVERT_TWIPS;
2927                 pItem->QueryValue( aState, (sal_uInt8)nSubId );
2928             }
2929             rAny = aState;
2930 
2931             return SFX_ITEM_AVAILABLE;
2932         }
2933 	}
2934 
2935 	return SFX_ITEM_DISABLED;
2936 }
2937 
2938 sal_Bool SfxDispatcher::IsReadOnlyShell_Impl( sal_uInt16 nShell ) const
2939 {
2940 	sal_uInt16 nShellCount = pImp->aStack.Count();
2941 	if ( nShell < nShellCount )
2942 	{
2943         SfxShell* pShell = pImp->aStack.Top( nShell );
2944         if( pShell->ISA( SfxModule ) || pShell->ISA( SfxApplication ) || pShell->ISA( SfxViewFrame ) )
2945             return sal_False;
2946         else
2947             return pImp->bReadOnly;
2948 	}
2949 	else if ( pImp->pParent )
2950 		return pImp->pParent->IsReadOnlyShell_Impl( nShell - nShellCount );
2951 	return sal_True;
2952 }
2953 
2954 // Ein dirty trick, um an die Methoden der private base class von
2955 // SfxShellStack_Impl heranzukommen
2956 class StackAccess_Impl : public SfxShellStack_Implarr_
2957 {};
2958 
2959 void SfxDispatcher::InsertShell_Impl( SfxShell& rShell, sal_uInt16 nPos )
2960 {
2961 	Flush();
2962 
2963 	// Der cast geht, weil SfxShellStack_Impl keine eigenen member hat
2964 	((StackAccess_Impl*) (&pImp->aStack))->Insert( nPos, &rShell );
2965 	rShell.SetDisableFlags( pImp->nDisableFlags );
2966 	rShell.DoActivate_Impl(pImp->pFrame, sal_True);
2967 
2968 	if ( !SFX_APP()->IsDowning() )
2969 	{
2970 		pImp->bUpdated = sal_False;
2971 		pImp->pCachedServ1 = 0;
2972 		pImp->pCachedServ2 = 0;
2973 		InvalidateBindings_Impl(sal_True);
2974 	}
2975 }
2976 
2977 void SfxDispatcher::RemoveShell_Impl( SfxShell& rShell )
2978 {
2979 	Flush();
2980 
2981 	// Der cast geht, weil SfxShellStack_Impl keine eigenen member hat
2982 	StackAccess_Impl& rStack = *((StackAccess_Impl*) (&pImp->aStack));
2983 	sal_uInt16 nCount = rStack.Count();
2984 	for ( sal_uInt16 n=0; n<nCount; ++n )
2985 	{
2986 		if ( rStack[n] == &rShell )
2987 		{
2988 			rStack.Remove( n );
2989 			rShell.SetDisableFlags( 0 );
2990 			rShell.DoDeactivate_Impl(pImp->pFrame, sal_True);
2991 			break;
2992 		}
2993 	}
2994 
2995 	if ( !SFX_APP()->IsDowning() )
2996 	{
2997 		pImp->bUpdated = sal_False;
2998 		pImp->pCachedServ1 = 0;
2999 		pImp->pCachedServ2 = 0;
3000 		InvalidateBindings_Impl(sal_True);
3001 	}
3002 }
3003 
3004 sal_Bool SfxDispatcher::IsAllowed
3005 (
3006 	sal_uInt16 nSlot
3007 ) const
3008 /*
3009 	[Beschreibung]
3010 	Die Methode prueft, ob der Zugriff auf diese Schnittstelle erlaubt ist.
3011 	*/
3012 {
3013 	if ( !pImp->pDisableList )
3014 	{
3015 		return sal_True;
3016 	}
3017 
3018 	// BinSearch in der DisableListe
3019 	SvUShorts& rList = *pImp->pDisableList;
3020 	sal_uInt16 nCount = rList.Count();
3021 	sal_uInt16 nLow = 0, nMid = 0, nHigh;
3022 	sal_Bool bFound = sal_False;
3023 	nHigh = nCount - 1;
3024 
3025 	while ( !bFound && nLow <= nHigh )
3026 	{
3027 		nMid = (nLow + nHigh) >> 1;
3028 		DBG_ASSERT( nMid < nCount, "bsearch ist buggy" );
3029 
3030 		int nDiff = (int) nSlot - (int) rList[nMid];
3031 		if ( nDiff < 0)
3032 		{
3033 			if ( nMid == 0 )
3034 				break;
3035 			nHigh = nMid - 1;
3036 		}
3037 		else if ( nDiff > 0 )
3038 		{
3039 			nLow = nMid + 1;
3040 			if ( nLow == 0 )
3041 				break;
3042 		}
3043 		else
3044 			bFound = sal_True;
3045 	}
3046 
3047 #ifdef _DEBUG
3048 	// Slot in der Liste gefunden ?
3049 	sal_uInt16 nPos = bFound ? nMid : nLow;
3050 
3051 	DBG_ASSERT( nPos <= nCount, "" );
3052 	DBG_ASSERT( nPos == nCount || nSlot <= rList[nPos], "" );
3053 	DBG_ASSERT( nPos == 0 || nSlot > rList[nPos-1], "" );
3054 	DBG_ASSERT( ( (nPos+1) >= nCount ) || nSlot < rList[nPos+1], "" );
3055 #endif
3056 
3057 	return !bFound;
3058 }
3059 
3060 void SfxDispatcher::InvalidateBindings_Impl( sal_Bool bModify )
3061 {
3062 	// App-Dispatcher?
3063 	if ( IsAppDispatcher() )
3064 	{
3065 		for ( SfxViewFrame *pFrame = SfxViewFrame::GetFirst();
3066 				pFrame;
3067 				pFrame = SfxViewFrame::GetNext( *pFrame ) )
3068 			pFrame->GetBindings().InvalidateAll(bModify);
3069 	}
3070 	else
3071 	{
3072 		SfxDispatcher *pDisp = GetBindings()->GetDispatcher_Impl();
3073 		while ( pDisp )
3074 		{
3075 			if ( pDisp == this )
3076 			{
3077 				GetBindings()->InvalidateAll( bModify );
3078 				break;
3079 			}
3080 
3081 			pDisp = pDisp->pImp->pParent;
3082 		}
3083 	}
3084 }
3085 
3086 sal_Bool SfxDispatcher::IsUpdated_Impl() const
3087 {
3088 	return pImp->bUpdated;
3089 }
3090 
3091 void SfxDispatcher::SetDisableFlags( sal_uInt32 nFlags )
3092 {
3093 	pImp->nDisableFlags = nFlags;
3094 	for ( int i = int(pImp->aStack.Count()) - 1; i >= 0; --i )
3095 		pImp->aStack.Top( (sal_uInt16) i )->SetDisableFlags( nFlags );
3096 }
3097 
3098 sal_uInt32 SfxDispatcher::GetDisableFlags() const
3099 {
3100 	return pImp->nDisableFlags;
3101 }
3102 
3103 SfxModule* SfxDispatcher::GetModule() const
3104 {
3105 	for ( sal_uInt16 nShell = 0;; ++nShell )
3106 	{
3107         SfxShell *pSh = GetShell(nShell);
3108         if ( pSh == NULL )
3109             return 0;
3110 		if ( pSh->ISA(SfxModule) )
3111 			return (SfxModule*) pSh;
3112 	}
3113 }
3114