1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: dispatch.cxx,v $
10 * $Revision: 1.56.126.1 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_sfx2.hxx"
33 #include <com/sun/star/beans/XPropertySet.hpp>
34 #include <com/sun/star/frame/XDispatchRecorderSupplier.hpp>
35 #include <com/sun/star/frame/XLayoutManager.hpp>
36 #include <svtools/itempool.hxx>
37 #include <svtools/itemiter.hxx>
38 #include <svtools/whiter.hxx>
39 #include <svtools/intitem.hxx>
40 #ifndef _SFXEITEM_HXX //autogen
41 #include <svtools/eitem.hxx>
43 #include <svtools/undo.hxx>
44 #ifndef _WRKWIN_HXX //autogen
45 #include <vcl/wrkwin.hxx>
47 #include <svtools/ttprops.hxx>
50 #include <stdlib.h> // wg. bsearch
52 #define _SVSTDARR_ULONGS
53 #include <svtools/svstdarr.hxx>
54 #include <svtools/helpopt.hxx>
55 #include <com/sun/star/frame/XLayoutManager.hpp>
56 #include <com/sun/star/beans/XPropertySet.hpp>
62 #include "appdata.hxx"
63 #include "sfxhelp.hxx"
64 #include <sfx2/dispatch.hxx>
65 #include <sfx2/minstack.hxx>
66 #include <sfx2/msg.hxx>
67 #include <sfx2/objface.hxx>
68 #include <sfx2/bindings.hxx>
69 #include <sfx2/request.hxx>
70 #include <sfx2/app.hxx>
71 #include <sfx2/hintpost.hxx>
72 #include "slotserv.hxx"
73 #include <sfx2/ipclient.hxx>
74 #include "sfxtypes.hxx"
75 #include <sfx2/macrconf.hxx>
76 #include <sfx2/viewfrm.hxx>
77 #include <sfx2/viewsh.hxx>
78 #include <sfx2/childwin.hxx>
79 #include <sfx2/docfac.hxx>
80 #include <sfx2/msgpool.hxx>
81 #include <sfx2/module.hxx>
82 #include <sfx2/topfrm.hxx>
83 #include <sfx2/sfxuno.hxx>
84 #include <sfx2/docfile.hxx>
85 #include <sfx2/mnumgr.hxx>
86 #include "workwin.hxx"
88 namespace css
= ::com::sun::star
;
90 //==================================================================
91 DBG_NAME(SfxDispatcherFlush
)
92 DBG_NAME(SfxDispatcherFillState
)
94 //==================================================================
95 typedef SfxRequest
* SfxRequestPtr
;
96 SV_IMPL_PTRARR( SfxItemPtrArray
, SfxPoolItemPtr
);
97 SV_DECL_PTRARR_DEL( SfxRequestPtrArray
, SfxRequestPtr
, 4, 4 )
98 SV_IMPL_PTRARR( SfxRequestPtrArray
, SfxRequestPtr
);
100 DECL_PTRSTACK(SfxShellStack_Impl
, SfxShell
*, 8, 4 );
101 //==================================================================
116 SfxToDo_Impl( bool bOpPush
, bool bOpDelete
, bool bOpUntil
, SfxShell
& rCluster
)
117 : pCluster(&rCluster
)
124 bool operator==( const SfxToDo_Impl
& rWith
) const
125 { return pCluster
==rWith
.pCluster
&& bPush
==rWith
.bPush
; }
128 DECL_OBJSTACK(SfxToDoStack_Impl
, SfxToDo_Impl
, 8, 4);
129 IMPL_OBJSTACK(SfxToDoStack_Impl
, SfxToDo_Impl
);
131 struct SfxObjectBars_Impl
133 sal_uInt32 nResId
; // Resource - und ConfigId der Toolbox
134 sal_uInt16 nMode
; // spezielle Sichtbarkeitsflags
136 SfxInterface
* pIFace
;
138 SfxObjectBars_Impl() :
143 //------------------------------------------------------------------
145 struct SfxDispatcher_Impl
147 SfxRequestPtrArray aReqArr
;
148 const SfxSlotServer
* pCachedServ1
; // zuletzt gerufene Message
149 const SfxSlotServer
* pCachedServ2
; // vorletzt gerufene Message
150 SfxShellStack_Impl aStack
; // aktive Funktionalitaet
151 Timer aTimer
; // fuers flushen
152 SfxToDoStack_Impl aToDoStack
; // nicht abgearb. Push/Pop
153 SfxViewFrame
* pFrame
; // 0 oder zugeh"or. Frame
154 SfxDispatcher
* pParent
; // z.B. AppDispatcher, ggf. 0
155 SfxHintPosterRef xPoster
; // asynchrones Execute
156 sal_Bool bFlushing
; // sal_True waehrend Flush //?
157 sal_Bool bUpdated
; // Update_Impl gelaufen
158 sal_Bool bLocked
; // kein Execute
159 sal_Bool bInvalidateOnUnlock
;// da fragte jemand
160 sal_Bool bActive
; // nicht verwechseln mit gesetzt!
161 sal_Bool
* pInCallAliveFlag
; // dem Stack den Dtor anzeigen
162 SfxObjectBars_Impl aObjBars
[SFX_OBJECTBAR_MAX
];
163 SfxObjectBars_Impl aFixedObjBars
[SFX_OBJECTBAR_MAX
];
165 sal_uInt16 nActionLevel
; // in EnterAction
166 sal_uInt32 nEventId
; // EventId UserEvent
167 sal_Bool bUILocked
; // Update abgeklemmt (!zappeln)
168 sal_Bool bNoUI
; // UI nur vom Parent Dispatcher
169 sal_Bool bReadOnly
; // Dokument ist ReadOnly
170 sal_Bool bQuiet
; // nur parent dispatcher verwenden
171 sal_Bool bModal
; // nur Slots vom Parent-Dispatcher
173 sal_Bool bFilterEnabling
; // sal_True=filter enabled slots, 2==ReadOnlyDoc uebersteuert
174 sal_uInt16 nFilterCount
; // Anzahl der SIDs in pFilterSIDs
175 const sal_uInt16
* pFilterSIDs
; // sortiertes Array von SIDs
176 sal_uInt16 nStandardMode
; // ExecuteMode f. PlugInDispatcher
177 SvUShorts
* pDisableList
;
178 sal_uInt32 nDisableFlags
;
181 #define NO_OBJECTBAR 0
182 #define OWN_OBJECTBAR 1
183 #define OTHER_OBJECTBAR 2
185 //------------------------------------------------------------------
187 #define SFX_FLUSH_TIMEOUT 50
189 //====================================================================
190 sal_Bool
SfxDispatcher::IsLocked( sal_uInt16
) const
194 Mit dieser Methode kann festgestellt werden, ob der SfxDispatcher
195 gesperrt oder freigegeben ist. Ein gesperrter SfxDispatcher
196 f"uhrt keine <SfxRequest>s mehr aus und liefert keine
197 Status-Informationen mehr. Er verh"alt sich so als w"aren alle
200 Der Dispatcher gilt auch als gesperrt, wenn alle Dispatcher
201 gelockt sind (<SfxApplication::LockDispatcher()>) oder der zugeh"orige
202 Top-Frame im modal-mode ist und der angegebene Slot Frame-spezifisch
203 (also nicht von der Application) bedient wird.
207 return pImp
->bLocked
;
210 //--------------------------------------------------------------------
211 sal_Bool
SfxDispatcher::IsAppDispatcher() const
215 Mit dieser Methode l"a\st sich festellen, ob der SfxDispacher der
216 Applikations-Dispatcher ist.
222 Es ist der Applikations-Dispatcher.
225 Es ist ein Dispatcher eines SfxViewFrame.
229 return !pImp
->pFrame
;
232 //--------------------------------------------------------------------
233 int SfxDispatcher::Call_Impl( SfxShell
& rShell
, const SfxSlot
&rSlot
, SfxRequest
&rReq
, sal_Bool bRecord
)
237 Hilfsfunktion zum pr"ufen, ob ein Slot executed werden darf und
238 der Execution selbst.
242 SFX_STACK(SfxDispatcher::Call_Impl
);
244 // darf der Slot gerufen werden (i.S.v. enabled)
245 SfxApplication
*pSfxApp
= SFX_APP();
246 if ( rSlot
.IsMode(SFX_SLOT_FASTCALL
) || rShell
.CanExecuteSlot_Impl(rSlot
) )
250 // ggf. Recording anwerfen
251 com::sun::star::uno::Reference
< com::sun::star::frame::XFrame
> xFrame(
252 GetFrame()->GetFrame()->GetFrameInterface(),
253 com::sun::star::uno::UNO_QUERY
);
255 com::sun::star::uno::Reference
< com::sun::star::beans::XPropertySet
> xSet(
257 com::sun::star::uno::UNO_QUERY
);
261 com::sun::star::uno::Any aProp
= xSet
->getPropertyValue(::rtl::OUString::createFromAscii("DispatchRecorderSupplier"));
262 com::sun::star::uno::Reference
< com::sun::star::frame::XDispatchRecorderSupplier
> xSupplier
;
263 com::sun::star::uno::Reference
< com::sun::star::frame::XDispatchRecorder
> xRecorder
;
266 xRecorder
= xSupplier
->getDispatchRecorder();
268 if ( bRecord
&& xRecorder
.is() && !rSlot
.IsMode(SFX_SLOT_NORECORD
) )
269 rReq
.Record_Impl( rShell
, rSlot
, xRecorder
, GetFrame() );
273 // Alles holen, was gebraucht wird, da der Slot den Execute evtl. nicht
274 // "uberlebt, falls es ein 'Pseudoslot' f"ur Macros oder Verben ist
275 sal_Bool bAutoUpdate
= rSlot
.IsMode(SFX_SLOT_AUTOUPDATE
);
276 SFX_REQUEST_ARG(rReq
, pOrigItem
, SfxExecuteItem
, SID_SUBREQUEST
, sal_False
);
277 SfxExecuteItem
*pExecuteItem
= pOrigItem
278 ? (SfxExecuteItem
*)pOrigItem
->Clone()
281 // ggf. TabPage-ID setzen
282 SfxAppData_Impl
*pAppData
= pSfxApp
->Get_Impl();
283 SFX_REQUEST_ARG(rReq
, pTabPageItem
, SfxUInt16Item
, SID_TABPAGE
, sal_False
);
286 pAppData
->nAutoTabPageId
= pTabPageItem
->GetValue();
287 rReq
.RemoveItem( SID_TABPAGE
); // sonst ArgCount > 0 => Seiteneff.
290 // API-Call-Klammerung und Document-Lock w"ahrend des Calls
292 // 'this' mu\s im Dtor bescheid sagen
293 sal_Bool bThisDispatcherAlive
= sal_True
;
294 sal_Bool
*pOldInCallAliveFlag
= pImp
->pInCallAliveFlag
;
295 pImp
->pInCallAliveFlag
= &bThisDispatcherAlive
;
297 SfxViewFrame
* pView
= GetFrame();
299 pView
= SfxViewFrame::Current();
301 SfxHelp::OpenHelpAgent( pView
->GetFrame(), rReq
.GetSlot() );
303 SfxExecFunc pFunc
= rSlot
.GetExecFnc();
304 rShell
.CallExec( pFunc
, rReq
);
306 // falls 'this' noch lebt
307 if ( bThisDispatcherAlive
)
308 pImp
->pInCallAliveFlag
= pOldInCallAliveFlag
;
311 if ( pOldInCallAliveFlag
)
313 // auch verschachtelte Stack-Frames sch"utzen
314 *pOldInCallAliveFlag
= sal_False
;
317 // do nothing after this object is dead
318 return rReq
.IsDone();
322 // TabPage-ID und Executing-SID zurueck setzen
324 pAppData
->nAutoTabPageId
= 0;
328 Execute( *pExecuteItem
);
334 SfxBindings
*pBindings
= GetBindings();
336 // bei AutoUpdate sofort updaten; "Pseudoslots" d"urfen nicht
338 if ( bAutoUpdate
&& pBindings
)
340 const SfxSlot
* pSlave
= rSlot
.GetLinkedSlot();
343 // bei Enum-Slots irgendeinen gebundenen Slave-Slot nehmen
344 while (!pBindings
->IsBound(pSlave
->GetSlotId()) && pSlave
!= &rSlot
)
345 pSlave
= pSlave
->GetLinkedSlot();
346 pBindings
->Invalidate(pSlave
->GetSlotId());
347 pBindings
->Update(pSlave
->GetSlotId());
351 pBindings
->Invalidate(rSlot
.GetSlotId());
352 pBindings
->Update(rSlot
.GetSlotId());
363 //====================================================================
364 void SfxDispatcher::Construct_Impl( SfxDispatcher
* pParent
)
366 pImp
= new SfxDispatcher_Impl
;
368 SfxApplication
*pSfxApp
= SFX_APP();
370 pImp
->pCachedServ1
= 0;
371 pImp
->pCachedServ2
= 0;
372 pImp
->bFlushing
= sal_False
;
373 pImp
->bUpdated
= sal_False
;
374 pImp
->bLocked
= sal_False
;
375 pImp
->bActive
= sal_False
;
376 pImp
->pParent
= NULL
;
377 pImp
->bUILocked
= sal_False
;
378 pImp
->bNoUI
= sal_False
;
379 pImp
->bReadOnly
= sal_False
;
380 pImp
->bQuiet
= sal_False
;
381 pImp
->bModal
= sal_False
;
382 pImp
->pInCallAliveFlag
= 0;
383 pImp
->bFilterEnabling
= sal_False
;
384 pImp
->nFilterCount
= 0;
385 pImp
->pFilterSIDs
= 0;
386 pImp
->nStandardMode
= 0;
387 pImp
->pDisableList
= pSfxApp
->GetDisabledSlotList_Impl();
388 pImp
->nDisableFlags
= 0;
390 pImp
->pParent
= pParent
;
392 pImp
->bInvalidateOnUnlock
= sal_False
;
393 pImp
->nActionLevel
= 0;
395 for (sal_uInt16 n
=0; n
<SFX_OBJECTBAR_MAX
; n
++)
396 pImp
->aObjBars
[n
].nResId
= 0;
398 GenLink
aGenLink( LINK(this, SfxDispatcher
, PostMsgHandler
) );
400 pImp
->xPoster
= new SfxHintPoster(aGenLink
);
402 pImp
->aTimer
.SetTimeout(SFX_FLUSH_TIMEOUT
);
403 pImp
->aTimer
.SetTimeoutHdl( LINK(this, SfxDispatcher
, EventHdl_Impl
) );
406 SfxDispatcher::SfxDispatcher( SfxDispatcher
* pParent
)
408 Construct_Impl( pParent
);
412 SfxDispatcher::SfxDispatcher( SfxViewFrame
*pViewFrame
)
416 Der Konstruktor der Klasse SfxDispatcher legt einen leeren Stack
417 von <SfxShell>-Pointern an. Er ist initial nicht gelockt und gilt als
424 SfxViewFrame
*pFrame
= pViewFrame
->GetParentViewFrame();
426 Construct_Impl( pFrame
->GetDispatcher() );
432 pImp
->pFrame
= pViewFrame
;
435 //====================================================================
436 SfxDispatcher::~SfxDispatcher()
440 Der Destruktor der Klasse SfxDispatcher darf nicht gerufen werden,
441 wenn die SfxDispatcher-Instanz aktiv ist. Es d"urfen sich allerdings
442 noch <SfxShell>-Pointer auf dem Stack befinden.
447 ByteString
sTemp( "Delete Dispatcher " );
448 sTemp
+= ByteString::CreateFromInt64( (sal_uIntPtr
)this );
449 DBG_TRACE( sTemp
.GetBuffer() );
450 DBG_ASSERT( !pImp
->bActive
, "deleting active Dispatcher" );
453 // Damit in LeaveRegistrations kein Timer per Reschedule in PlugComm
456 pImp
->xPoster
->SetEventHdl( Link() );
458 // die Stack-Varialblem in Call_Impl benachrichtigen
459 if ( pImp
->pInCallAliveFlag
)
460 *pImp
->pInCallAliveFlag
= sal_False
;
462 // Bindings und App besorgen
463 SfxApplication
*pSfxApp
= SFX_APP();
464 SfxBindings
* pBindings
= GetBindings();
466 // if (pImp->nEventId)
467 // pSfxApp->RemoveEventHdl(pImp->nEventId);
469 // wenn noch nicht flushed, die Bindings wiederbeleben
470 if ( pBindings
&& !pSfxApp
->IsDowning() && !bFlushed
)
471 pBindings
->DLEAVEREGISTRATIONS();
473 // ggf. bei den Bindings abmelden
476 if ( pBindings
->GetDispatcher_Impl() == this)
477 pBindings
->SetDispatcher(0);
478 pBindings
= pBindings
->GetSubBindings_Impl();
484 //====================================================================
485 void SfxDispatcher::Pop
487 SfxShell
& rShell
, /* Die vom Stack zu nehmende SfxShell-Instanz. */
489 sal_uInt16 nMode
/* SFX_SHELL_POP_UNTIL
490 Es werden auch alle "uber 'rShell' liegenenden
491 SfxShell's vom Stack genommen.
494 Alle tats"achlich vom Stack genommenen
495 SfxShells werden gel"oscht.
497 SFX_SHELL_PUSH (InPlace use only)
498 Die Shell wird gepusht. */
502 Mit dieser Methode wird eine oder mehrere <SfxShell> vom SfxDispatcher
503 gepoppt. Die SfxShell wird zun"achst zum poppen vermerkt und
504 es wird ein Timer aufgesetzt. Erst bei Ablauf des Timers wird
505 tats"achlich gepoppt (<SfxDispatcher::Flush()>) und die <SfxBindings>
506 werden invalidiert. W"ahrend der Timer l"auft gleichen sich
507 entgegengesetzte Push und Pop Befehle mit derselben SfxShell aus.
512 DBG_ASSERT( rShell
.GetInterface(),
513 "pushing SfxShell without previous RegisterInterface()" );
514 DBG_ASSERT( pImp
->nActionLevel
== 0, "Push or Pop within Action" );
515 // DBG_ASSERT( SFX_APP()->IsInAsynchronCall_Impl(),
516 // "Dispatcher Push/Pop in synchron-call-stack" );
518 bool bDelete
= (nMode
& SFX_SHELL_POP_DELETE
) == SFX_SHELL_POP_DELETE
;
519 bool bUntil
= (nMode
& SFX_SHELL_POP_UNTIL
) == SFX_SHELL_POP_UNTIL
;
520 bool bPush
= (nMode
& SFX_SHELL_PUSH
) == SFX_SHELL_PUSH
;
522 SfxApplication
*pSfxApp
= SFX_APP();
525 ByteString
aMsg( "SfxDispatcher(" );
526 aMsg
+= ByteString::CreateFromInt64( (sal_uIntPtr
) this );
527 aMsg
+= bPush
? ")::Push(" : ")::Pop(";
528 if ( rShell
.GetInterface() )
529 aMsg
+= rShell
.GetInterface()->GetClassName();
531 aMsg
+= ByteString::CreateFromInt64( (sal_uIntPtr
) &rShell
);
532 aMsg
+= bDelete
? ") with delete" : ")";
533 DbgTrace( aMsg
.GetBuffer() );
536 // gleiche Shell wie on-Top des ToDo-Stacks?
537 if ( pImp
->aToDoStack
.Count() && pImp
->aToDoStack
.Top().pCluster
== &rShell
)
539 // inverse Actions heben sich auf
540 if ( pImp
->aToDoStack
.Top().bPush
!= bPush
)
541 pImp
->aToDoStack
.Pop();
544 DBG_ASSERT( bPush
, "SfxInterface pushed more than once" );
545 DBG_ASSERT( !bPush
, "SfxInterface popped more than once" );
550 // ::com::sun::star::chaos::Action merken
551 pImp
->aToDoStack
.Push( SfxToDo_Impl(bPush
, bDelete
, bUntil
, rShell
) );
554 DBG_TRACE("Unflushed dispatcher!");
555 bFlushed
= sal_False
;
556 pImp
->bUpdated
= sal_False
;
558 // Bindings schlafen legen
559 SfxBindings
* pBindings
= GetBindings();
561 pBindings
->DENTERREGISTRATIONS();
565 if ( !pSfxApp
->IsDowning() && pImp
->aToDoStack
.Count() )
567 //! if (SFX_APP()->AnyInput(INPUT_KEYBOARD | INPUT_MOUSE) )
568 //! AnyInput haut nicht hin; hier muss noch ein Kriterium gefunden
569 //! werden. Solange wieder immer mit Timer.
573 // Kein sofortiges Update gewuenscht
574 pImp
->aTimer
.SetTimeout(SFX_FLUSH_TIMEOUT
);
575 pImp
->aTimer
.SetTimeoutHdl( LINK(this, SfxDispatcher
, EventHdl_Impl
) );
576 pImp
->aTimer
.Start();
580 // Schnellstmoegliches Update (sollte Normalfall sein)
582 GetpApp()->PostUserEvent(pImp
->nEventId
, (void*)0);
587 // doch nichts zu tun
590 // ggf. Bindings wieder aufwecken
591 if ( !pImp
->aToDoStack
.Count() )
593 SfxBindings
* pBindings
= GetBindings();
595 pBindings
->DLEAVEREGISTRATIONS();
600 //--------------------------------------------------------------------
602 IMPL_LINK_INLINE_START( SfxDispatcher
, EventHdl_Impl
, void *, pvoid
)
606 Dieser Handler wird nach <SfxDispatcher::Invalidate()> oder Bewegungen
607 auf dem Stack (<SfxDispatcher::Push()> und <SfxDispatcher::Pop()) gerufen.
609 Er flusht den Stack, falls er dirty ist, f"uhrt also die ausstehenden
610 Push und Pop Befehle tats"achlich aus.
614 (void)pvoid
; // unused
619 SfxBindings
* pBindings
= GetBindings();
621 pBindings
->StartUpdate_Impl(sal_False
);
624 IMPL_LINK_INLINE_END( SfxDispatcher
, EventHdl_Impl
, void *, pvoid
)
626 //--------------------------------------------------------------------
627 sal_Bool
SfxDispatcher::CheckVirtualStack( const SfxShell
& rShell
, sal_Bool bDeep
)
631 Mit dieser Methode kann gepr"uft werden, ob sich die <SfxShell> rShell
632 auf dem Stack befindet, wenn er geflusht w"are. Dabei wird der
633 SfxDispatcher jedoch nicht tats"achlich geflusht.
635 Diese Methode ist u.a. dazu gedacht, Assertions zu erm"oglichen, ohne
636 als Seiteneffekt den SfxDispathcer flushen zu m"ussen.
641 SFX_STACK(SfxDispatcher::CheckVirtualStack
);
643 SfxShellStack_Impl
aStack( pImp
->aStack
);
644 for ( short nToDo
= pImp
->aToDoStack
.Count()-1; nToDo
>= 0; --nToDo
)
646 SfxToDo_Impl
aToDo( pImp
->aToDoStack
.Top(nToDo
) );
648 aStack
.Push( (SfxShell
*) aToDo
.pCluster
);
651 SfxShell
* pPopped
= 0;
654 DBG_ASSERT( aStack
.Count(), "popping from empty stack" );
655 pPopped
= aStack
.Pop();
657 while ( aToDo
.bUntil
&& pPopped
!= aToDo
.pCluster
);
658 DBG_ASSERT( pPopped
== aToDo
.pCluster
, "popping unpushed SfxInterface" );
664 bReturn
= aStack
.Contains(&rShell
);
666 bReturn
= aStack
.Top() == &rShell
;
670 //--------------------------------------------------------------------
671 sal_uInt16
SfxDispatcher::GetShellLevel( const SfxShell
& rShell
)
675 Ermittelt die Position einer SfxShell im Stack des Dispatchers.
676 Dazu wird dieser ggf. zuvor geflusht.
681 sal_uInt16 == USRT_MAX
682 Die SfxShell befindet sich nicht auf
683 diesem SfxDispatcher.
686 Position der SfxShell auf dem Dispatcher
687 von oben mit 0 beginnend gez"ahlt.
692 SFX_STACK(SfxDispatcher::GetShellLevel
);
695 for ( sal_uInt16 n
= 0; n
< pImp
->aStack
.Count(); ++n
)
696 if ( pImp
->aStack
.Top( n
) == &rShell
)
700 sal_uInt16 nRet
= pImp
->pParent
->GetShellLevel(rShell
);
701 if ( nRet
== USHRT_MAX
)
703 return nRet
+ pImp
->aStack
.Count();
709 //--------------------------------------------------------------------
710 SfxShell
*SfxDispatcher::GetShell(sal_uInt16 nIdx
) const
714 Liefert einen Pointer auf die <SfxShell>, welche sich an der Position
715 nIdx (von oben, letzt-gepushte liegt bei 0) auf dem Stack befindet.
717 Dabei wird der SfxDispatcher nicht geflusht.
719 Ist der Stack nicht tief genug, wird ein 0-Pointer zur"uckgegeben.
725 sal_uInt16 nShellCount
= pImp
->aStack
.Count();
726 if ( nIdx
< nShellCount
)
727 return pImp
->aStack
.Top(nIdx
);
728 else if ( pImp
->pParent
)
729 return pImp
->pParent
->GetShell( nIdx
- nShellCount
);
733 //--------------------------------------------------------------------
734 SfxBindings
* SfxDispatcher::GetBindings() const
738 Diese Methode liefert einen Pointer auf die <SfxBindings> Instanz
739 zur"uck, an die der SfxDispatcher gerade gebunden ist. Ein SfxDispatcher
740 ist nur dann an SfxBindings gebunden, wenn er <UI-aktiv> ist. Ist
741 er nicht UI-aktiv, wird ein 0-Pointer zur"uckgegeben.
743 Der zur"uckgegebene Pointer ist nur im <unmittelbaren Kontext> des
744 Methodenaufrufs g"ultig.
749 return &pImp
->pFrame
->GetBindings();
754 //--------------------------------------------------------------------
755 SfxViewFrame
* SfxDispatcher::GetFrame() const
759 Liefert einen Pointer auf die <SfxViewFrame> Instanz, der dieser
760 SfxDispatcher geh"ort. Falls es sich um den Applikations-Dispatcher
761 handelt, wird ein 0-Pointer zur"uckgegeben.
769 //--------------------------------------------------------------------
770 void SfxDispatcher::DoActivate_Impl( sal_Bool bMDI
, SfxViewFrame
* /* pOld */ )
774 Diese Methode steuert das Aktivieren eines Dispatchers.
776 Da der Applikations-Dispatcher immer aktiv ist, entweder als
777 Unterdispatcher des <SfxViewFrame>-Dispatchers oder selbst, wird
778 er nie als ganzes Aktiviert, sondern nur seine einzelnen <SfxShell>s
779 bei <SfxDispatcher::Push(SfxShell&)>.
781 Beim Aktivieren eines SfxDispatchers wird an allen auf seinem
782 Stack befindlichen SfxShells, beginnend mit der untersten, der Handler
783 <SfxShell::Activate(sal_Bool)> gerufen.
788 SFX_STACK(SfxDispatcher::DoActivate
);
792 ByteString
sTemp("Activate Dispatcher ");
793 sTemp
+= ByteString::CreateFromInt64( (sal_uIntPtr
) this );
794 DBG_TRACE(sTemp
.GetBuffer());
795 DBG_ASSERT( !pImp
->bActive
, "Activate-Fehler" );
797 pImp
->bActive
= sal_True
;
798 pImp
->bUpdated
= sal_False
;
799 SfxBindings
* pBindings
= GetBindings();
802 pBindings
->SetDispatcher(this);
803 pBindings
->SetActiveFrame( pImp
->pFrame
->GetFrame()->GetFrameInterface() );
809 ByteString
sTemp("Non-MDI-Activate Dispatcher");
810 sTemp
+= ByteString::CreateFromInt64( (sal_uIntPtr
) this );
811 DBG_TRACE( sTemp
.GetBuffer() );
815 if ( IsAppDispatcher() )
818 for ( int i
= int(pImp
->aStack
.Count()) - 1; i
>= 0; --i
)
819 pImp
->aStack
.Top( (sal_uInt16
) i
)->DoActivate_Impl(pImp
->pFrame
, bMDI
);
821 if ( bMDI
&& pImp
->pFrame
)
823 //SfxWorkWindow *pWorkWin = pImp->pFrame->GetFrame()->GetWorkWindow_Impl();
824 SfxBindings
*pBind
= GetBindings();
827 pBind
->HidePopupCtrls_Impl( FALSE
);
828 pBind
= pBind
->GetSubBindings_Impl();
831 pImp
->pFrame
->GetFrame()->GetWorkWindow_Impl()->HidePopups_Impl( FALSE
, FALSE
, 1 );
834 if ( pImp
->aToDoStack
.Count() )
838 // Kein sofortiges Update gewuenscht
839 pImp
->aTimer
.SetTimeout(SFX_FLUSH_TIMEOUT
);
840 pImp
->aTimer
.SetTimeoutHdl( LINK(this, SfxDispatcher
, EventHdl_Impl
) );
841 pImp
->aTimer
.Start();
845 // Schnellstmoegliches Update (sollte Normalfall sein)
847 GetpApp()->PostUserEvent(pImp
->nEventId
, (void*)0);
852 void SfxDispatcher::DoParentActivate_Impl()
854 for ( int i
= int(pImp
->aStack
.Count()) - 1; i
>= 0; --i
)
855 pImp
->aStack
.Top( (sal_uInt16
) i
)->ParentActivate();
858 //--------------------------------------------------------------------
859 void SfxDispatcher::DoDeactivate_Impl( sal_Bool bMDI
, SfxViewFrame
* pNew
)
863 Diese Methode steuert das Deaktivieren eines Dispatchers.
865 Da der Applikations-Dispatcher immer aktiv ist, entweder als
866 Unterdispatcher des <SfxViewFrame>-Dispatchers oder selbst, wird
867 er nie als ganzes Deaktiviert, sondern nur seine einzelnen <SfxShell>s
868 bei <SfxDispatcher::Pop(SfxShell&)>.
870 Beim Deaktivieren eines SfxDispatchers wird an allen auf seinem
871 Stack befindlichen SfxShells, beginnend mit der obersten, der Handler
872 <SfxShell::Deactivate(sal_Bool)> gerufen.
877 SFX_STACK(SfxDispatcher::DoDeactivate
);
879 SfxApplication
*pSfxApp
= SFX_APP();
883 DBG_TRACE(ByteString("Deactivate Dispatcher ").Append(ByteString::CreateFromInt64( (sal_uIntPtr
) this )).GetBuffer());
884 DBG_ASSERT( pImp
->bActive
, "Deactivate-Fehler" );
885 pImp
->bActive
= sal_False
;
887 if ( pImp
->pFrame
&& !(pImp
->pFrame
->GetObjectShell()->IsInPlaceActive() ) )
889 SfxWorkWindow
*pWorkWin
= pImp
->pFrame
->GetFrame()->GetWorkWindow_Impl();
892 for (sal_uInt16 n
=0; n
<pImp
->aChildWins
.Count();)
894 SfxChildWindow
*pWin
= pWorkWin
->GetChildWindow_Impl( (sal_uInt16
) ( pImp
->aChildWins
[n
] & 0xFFFF ) );
895 if (!pWin
|| (pWin
&& pWin
->GetAlignment() == SFX_ALIGN_NOALIGNMENT
))
896 pImp
->aChildWins
.Remove(n
);
904 DBG_TRACE( ByteString ("Non-MDI-DeActivate Dispatcher").Append(ByteString::CreateFromInt64( (sal_uIntPtr
) this )).GetBuffer() );
907 if ( IsAppDispatcher() && !pSfxApp
->IsDowning() )
910 for ( sal_uInt16 i
= 0; i
< pImp
->aStack
.Count(); ++i
)
911 pImp
->aStack
.Top(i
)->DoDeactivate_Impl(pImp
->pFrame
, bMDI
);
913 BOOL bHidePopups
= bMDI
&& pImp
->pFrame
;
914 if ( pNew
&& pImp
->pFrame
)
916 com::sun::star::uno::Reference
< com::sun::star::frame::XFrame
> xOldFrame(
917 pNew
->GetFrame()->GetFrameInterface()->getCreator(), com::sun::star::uno::UNO_QUERY
);
919 com::sun::star::uno::Reference
< com::sun::star::frame::XFrame
> xMyFrame(
920 GetFrame()->GetFrame()->GetFrameInterface(), com::sun::star::uno::UNO_QUERY
);
922 if ( xOldFrame
== xMyFrame
)
928 //SfxWorkWindow *pWorkWin = pImp->pFrame->GetFrame()->GetWorkWindow_Impl();
929 SfxBindings
*pBind
= GetBindings();
932 pBind
->HidePopupCtrls_Impl( TRUE
);
933 pBind
= pBind
->GetSubBindings_Impl();
936 pImp
->pFrame
->GetFrame()->GetWorkWindow_Impl()->HidePopups_Impl( TRUE
, FALSE
, 1 );
942 void SfxDispatcher::DoParentDeactivate_Impl()
944 for ( int i
= int(pImp
->aStack
.Count()) - 1; i
>= 0; --i
)
945 pImp
->aStack
.Top( (sal_uInt16
) i
)->ParentDeactivate();
948 //--------------------------------------------------------------------
949 int SfxDispatcher::GetShellAndSlot_Impl
951 sal_uInt16 nSlot
, // die zu suchende Slot-Id
952 SfxShell
** ppShell
, // die SfxShell, welche nSlot z.Zt. bedient
953 const SfxSlot
** ppSlot
, // der SfxSlot, welcher nSlot z.Zt. bedient
954 sal_Bool bOwnShellsOnly
,
955 sal_Bool bModal
, // trotz ModalMode
961 Diese Methode sucht im SfxDispatcher nach der <SfxShell>, von der
962 die Slot-Id nSlot zur Zeit bedient wird. Dazu wird der Dispatcher
969 Die SfxShell wurde gefunden, ppShell und ppSlot
973 Die SfxShell wurde nicht gefunden, ppShell und ppSlot
978 SFX_STACK(SfxDispatcher::GetShellAndSlot_Impl
);
982 if ( _FindServer(nSlot
, aSvr
, bModal
) )
984 if ( bOwnShellsOnly
&& aSvr
.GetShellLevel() >= pImp
->aStack
.Count() )
987 *ppShell
= GetShell(aSvr
.GetShellLevel());
988 *ppSlot
= aSvr
.GetSlot();
989 if ( 0 == (*ppSlot
)->GetExecFnc() && bRealSlot
)
990 *ppSlot
= (*ppShell
)->GetInterface()->GetRealSlot(*ppSlot
);
991 // Check only real slots as enum slots don't have an execute function!
992 if ( bRealSlot
&& ((0 == *ppSlot
) || (0 == (*ppSlot
)->GetExecFnc()) ))
996 ByteString
aMsg( nSlot
);
997 aMsg
+= " found in ";
998 aMsg
+= (*ppShell
)->GetInterface()->GetClassName();
999 DbgTrace( aMsg
.GetBuffer() );
1006 ByteString
aMsg( nSlot
);
1007 aMsg
+= " not found";
1008 DbgTrace( aMsg
.GetBuffer() );
1015 struct Executer : public SfxHint
1017 SfxRequest *pRequest;
1018 const SfxSlot* pSlot;
1021 Executer( SfxRequest* pReq, const SfxSlot* p, sal_uInt16 n )
1031 //--------------------------------------------------------------------
1032 void SfxDispatcher::_Execute
1034 SfxShell
& rShell
, // zu rufende <SfxShell>
1035 const SfxSlot
& rSlot
, // zu rufender <SfxSlot>
1036 SfxRequest
& rReq
, // auszuf"uhrende Funktion (Id und optional Parameter)
1037 SfxCallMode eCallMode
// synchron, asynchron oder wie beim Slot angegeben
1042 Diese Methode f"uhrt einen Request "uber einen gecachten <Slot-Server>
1048 DBG_ASSERT( !pImp
->bFlushing
, "recursive call to dispatcher" );
1049 DBG_ASSERT( !pImp
->aToDoStack
.Count(), "unprepared InPlace _Execute" );
1051 if ( IsLocked( rSlot
.GetSlotId() ) )
1054 sal_uInt16 nSlot
= rSlot
.GetSlotId();
1055 if ( SfxMacroConfig::IsMacroSlot( nSlot
) )
1056 SFX_APP()->GetMacroConfig()->RegisterSlotId( nSlot
);
1058 if ( (eCallMode
& SFX_CALLMODE_ASYNCHRON
) ||
1059 ( !(eCallMode
& SFX_CALLMODE_SYNCHRON
) &&
1060 rSlot
.IsMode(SFX_SLOT_ASYNCHRON
) ) )
1062 SfxDispatcher
*pDispat
= this;
1065 sal_uInt16 nShellCount
= pDispat
->pImp
->aStack
.Count();
1066 for ( sal_uInt16 n
=0; n
<nShellCount
; n
++ )
1068 if ( &rShell
== pDispat
->pImp
->aStack
.Top(n
) )
1070 if ( eCallMode
& SFX_CALLMODE_RECORD
)
1071 rReq
.AllowRecording( TRUE
);
1072 pDispat
->pImp
->xPoster
->Post(new SfxRequest(rReq
));
1073 // pDispat->pImp->xPoster->Post(new Executer(new SfxRequest(rReq), &rSlot, n ));
1078 pDispat
= pDispat
->pImp
->pParent
;
1082 Call_Impl( rShell
, rSlot
, rReq
, SFX_CALLMODE_RECORD
==(eCallMode
&SFX_CALLMODE_RECORD
) );
1085 //--------------------------------------------------------------------
1086 void MappedPut_Impl( SfxAllItemSet
&rSet
, const SfxPoolItem
&rItem
)
1090 Hilfsfunktion zum putten von rItem unter der im Pool des Item-Sets
1091 rSet geltenden Which-Id.
1095 // mit ggf. gemappter Which-Id putten
1096 const SfxItemPool
*pPool
= rSet
.GetPool();
1097 sal_uInt16 nWhich
= rItem
.Which();
1099 if ( pPool
->IsSlot(nWhich
) )
1101 if ( pPool
->HasMap() && pPool
->IsSlot(nWhich
) )
1103 nWhich
= pPool
->GetWhich(nWhich
);
1104 rSet
.Put( rItem
, nWhich
);
1107 //--------------------------------------------------------------------
1109 #ifndef SFX_USE_BINDINGS
1110 #define SFX_USE_BINDINGS 0x8000
1113 sal_uInt16
SfxDispatcher::ExecuteFunction( sal_uInt16 nSlot
, SfxPoolItem
**pArgs
,
1117 nMode
= pImp
->nStandardMode
;
1119 // via Bindings/Interceptor? (dann ist der Returnwert nicht exakt)
1120 sal_Bool bViaBindings
= SFX_USE_BINDINGS
== ( nMode
& SFX_USE_BINDINGS
);
1121 nMode
&= ~sal_uInt16(SFX_USE_BINDINGS
);
1122 if ( bViaBindings
&& GetBindings() )
1123 return GetBindings()->Execute( nSlot
, (const SfxPoolItem
**) pArgs
, nMode
)
1127 // sonst via Dispatcher
1128 if ( IsLocked(nSlot
) )
1130 SfxShell
*pShell
= 0;
1131 SfxCallMode eCall
= SFX_CALLMODE_SYNCHRON
;
1132 sal_uInt16 nRet
= EXECUTE_NO
;
1133 const SfxSlot
*pSlot
= 0;
1134 if ( GetShellAndSlot_Impl( nSlot
, &pShell
, &pSlot
, sal_False
, sal_False
) )
1136 // Ausf"uhrbarkeit vorher testen
1137 if ( pSlot
->IsMode( SFX_SLOT_FASTCALL
) ||
1138 pShell
->CanExecuteSlot_Impl( *pSlot
) )
1139 nRet
= EXECUTE_POSSIBLE
;
1141 if ( nMode
== EXECUTEMODE_ASYNCHRON
)
1142 eCall
= SFX_CALLMODE_ASYNCHRON
;
1143 else if ( nMode
== EXECUTEMODE_DIALOGASYNCHRON
&& pSlot
->IsMode( SFX_SLOT_HASDIALOG
) )
1144 eCall
= SFX_CALLMODE_ASYNCHRON
;
1145 else if ( pSlot
->GetMode() & SFX_SLOT_ASYNCHRON
)
1146 eCall
= SFX_CALLMODE_ASYNCHRON
;
1147 sal_Bool bDone
= sal_False
;
1148 if ( pArgs
&& *pArgs
)
1150 SfxAllItemSet
aSet( pShell
->GetPool() );
1151 for ( SfxPoolItem
**pArg
= pArgs
; *pArg
; ++pArg
)
1152 MappedPut_Impl( aSet
, **pArg
);
1153 SfxRequest
aReq( nSlot
, eCall
, aSet
);
1154 _Execute( *pShell
, *pSlot
, aReq
, eCall
);
1155 bDone
= aReq
.IsDone();
1159 SfxRequest
aReq( nSlot
, eCall
, pShell
->GetPool() );
1160 _Execute( *pShell
, *pSlot
, aReq
, eCall
);
1161 bDone
= aReq
.IsDone();
1168 sal_uInt16
SfxDispatcher::ExecuteFunction( sal_uInt16 nSlot
, const SfxItemSet
& rArgs
,
1172 nMode
= pImp
->nStandardMode
;
1175 // at the moment not implemented
1176 // via Bindings/Interceptor? (dann ist der Returnwert nicht exakt)
1177 sal_Bool bViaBindings = SFX_USE_BINDINGS == ( nMode & SFX_USE_BINDINGS );
1178 nMode &= ~sal_uInt16(SFX_USE_BINDINGS);
1179 if ( bViaBindings && GetBindings() )
1180 return GetBindings()->Execute( nSlot, rArgs, nMode )
1184 // sonst via Dispatcher
1185 if ( IsLocked(nSlot
) )
1187 SfxShell
*pShell
= 0;
1188 SfxCallMode eCall
= SFX_CALLMODE_SYNCHRON
;
1189 sal_uInt16 nRet
= EXECUTE_NO
;
1190 const SfxSlot
*pSlot
= 0;
1191 if ( GetShellAndSlot_Impl( nSlot
, &pShell
, &pSlot
, sal_False
, sal_False
) )
1193 // Ausf"uhrbarkeit vorher testen
1194 if ( pSlot
->IsMode( SFX_SLOT_FASTCALL
) ||
1195 pShell
->CanExecuteSlot_Impl( *pSlot
) )
1196 nRet
= EXECUTE_POSSIBLE
;
1198 if ( nMode
== EXECUTEMODE_ASYNCHRON
)
1199 eCall
= SFX_CALLMODE_ASYNCHRON
;
1200 else if ( nMode
== EXECUTEMODE_DIALOGASYNCHRON
&& pSlot
->IsMode( SFX_SLOT_HASDIALOG
) )
1201 eCall
= SFX_CALLMODE_ASYNCHRON
;
1202 else if ( pSlot
->GetMode() & SFX_SLOT_ASYNCHRON
)
1203 eCall
= SFX_CALLMODE_ASYNCHRON
;
1204 sal_Bool bDone
= sal_False
;
1205 SfxRequest
aReq( nSlot
, eCall
, rArgs
);
1206 _Execute( *pShell
, *pSlot
, aReq
, eCall
);
1207 bDone
= aReq
.IsDone();
1213 sal_uInt16
SfxDispatcher::GetSlotId( const String
& rCommand
)
1215 const SfxSlot
*pSlot
= GetSlot( rCommand
);
1217 return pSlot
->GetSlotId();
1221 const SfxSlot
* SfxDispatcher::GetSlot( const String
& rCommand
)
1223 // Anzahl der Shells auf den verkettenten Dispatchern z"ahlen
1225 sal_uInt16 nTotCount
= pImp
->aStack
.Count();
1226 if ( pImp
->pParent
)
1228 SfxDispatcher
*pParent
= pImp
->pParent
;
1231 nTotCount
= nTotCount
+ pParent
->pImp
->aStack
.Count();
1232 pParent
= pParent
->pImp
->pParent
;
1236 const SfxSlot
*pSlot
=NULL
;
1237 sal_uInt16 nFirstShell
= 0;
1238 for ( sal_uInt16 i
= nFirstShell
; i
< nTotCount
; ++i
)
1240 SfxShell
*pObjShell
= GetShell(i
);
1241 SfxInterface
*pIFace
= pObjShell
->GetInterface();
1242 pSlot
= pIFace
->GetSlot( rCommand
);
1250 //--------------------------------------------------------------------
1251 int SfxExecuteItem::operator==( const SfxPoolItem
& rItem
) const
1253 SfxExecuteItem
& rArg
= (SfxExecuteItem
& )rItem
;
1254 sal_uInt16 nCount
= Count();
1255 if( nCount
!= rArg
.Count() )
1258 if( *GetObject( nCount
) != *rArg
.GetObject( nCount
) )
1260 return eCall
== rArg
.eCall
;
1263 //--------------------------------------------------------------------
1264 SfxPoolItem
* SfxExecuteItem::Clone( SfxItemPool
* ) const
1266 return new SfxExecuteItem( *this );
1269 //--------------------------------------------------------------------
1270 SfxExecuteItem::SfxExecuteItem( const SfxExecuteItem
& rArg
)
1271 : SfxItemPtrArray(), SfxPoolItem( rArg
), nModifier( 0 )
1275 sal_uInt16 nCount
= rArg
.Count();
1276 for( sal_uInt16 nPos
= 0; nPos
< nCount
; nPos
++ )
1277 Insert( rArg
[ nPos
]->Clone(), nPos
);
1280 //--------------------------------------------------------------------
1281 SfxExecuteItem::SfxExecuteItem(
1282 sal_uInt16 nWhichId
, sal_uInt16 nSlotP
, SfxCallMode eModeP
,
1283 const SfxPoolItem
* pArg1
, ... ) :
1284 SfxPoolItem( nWhichId
), nSlot( nSlotP
), eCall( eModeP
), nModifier( 0 )
1287 va_start( pVarArgs
, pArg1
);
1288 for ( const SfxPoolItem
*pArg
= pArg1
; pArg
;
1289 pArg
= va_arg( pVarArgs
, const SfxPoolItem
* ) )
1290 Insert( pArg
->Clone(), Count() );
1294 //--------------------------------------------------------------------
1295 SfxExecuteItem::SfxExecuteItem(
1296 sal_uInt16 nWhichId
, sal_uInt16 nSlotP
, SfxCallMode eModeP
)
1297 : SfxPoolItem( nWhichId
), nSlot( nSlotP
), eCall( eModeP
), nModifier( 0 )
1301 //--------------------------------------------------------------------
1302 const SfxPoolItem
* SfxDispatcher::Execute( const SfxExecuteItem
& rItem
)
1304 const SfxPoolItem
** pPtr
= new const SfxPoolItem
*[ rItem
.Count() + 1 ];
1305 for( sal_uInt16 nPos
= rItem
.Count(); nPos
--; )
1306 pPtr
[ nPos
] = rItem
.GetObject( nPos
);
1307 pPtr
[ rItem
.Count() ] = 0;
1308 const SfxPoolItem
* pRet
= Execute(
1309 rItem
.GetSlot(), rItem
.GetCallMode(), pPtr
, rItem
.GetModifier() );
1311 delete [] (SfxPoolItem
**)pPtr
;
1316 //--------------------------------------------------------------------
1317 const SfxPoolItem
* SfxDispatcher::Execute(
1321 SfxItemSet
* pInternalArgs
,
1324 if ( IsLocked(nSlot
) )
1327 SfxShell
*pShell
= 0;
1328 const SfxSlot
*pSlot
= 0;
1329 if ( GetShellAndSlot_Impl( nSlot
, &pShell
, &pSlot
, sal_False
,
1330 SFX_CALLMODE_MODAL
==(nCall
&SFX_CALLMODE_MODAL
) ) )
1332 SfxAllItemSet
aSet( pShell
->GetPool() );
1335 SfxItemIter
aIter(*pArgs
);
1336 for ( const SfxPoolItem
*pArg
= aIter
.FirstItem();
1338 pArg
= aIter
.NextItem() )
1339 MappedPut_Impl( aSet
, *pArg
);
1341 SfxRequest
aReq( nSlot
, nCall
, aSet
);
1343 aReq
.SetInternalArgs_Impl( *pInternalArgs
);
1344 aReq
.SetModifier( nModi
);
1346 _Execute( *pShell
, *pSlot
, aReq
, nCall
);
1347 return aReq
.GetReturnValue();
1352 //--------------------------------------------------------------------
1353 const SfxPoolItem
* SfxDispatcher::Execute
1355 sal_uInt16 nSlot
, // die Id der auszufuehrenden Funktion
1356 SfxCallMode eCall
, // SFX_CALLMODE_SYNCRHON, ..._ASYNCHRON oder ..._SLOT
1357 const SfxPoolItem
**pArgs
, // 0-terminiertes C-Array von Parametern
1359 const SfxPoolItem
**pInternalArgs
// 0-terminiertes C-Array von Parametern
1364 Methode zum Ausf"uhren eines <SfxSlot>s "uber die Slot-Id.
1369 const SfxPoolItem* Pointer auf ein bis zum n"achsten Durchlauf
1370 der Message-Loop g"ultiges SfxPoolItem,
1371 welches den R"uckgabewert enth"alt.
1373 Oder ein 0-Pointer, wenn die Funktion nicht
1374 ausgef"uhrt wurde (z.B. Abbruch durch den
1379 if ( IsLocked(nSlot
) )
1382 SfxShell
*pShell
= 0;
1383 const SfxSlot
*pSlot
= 0;
1384 if ( GetShellAndSlot_Impl( nSlot
, &pShell
, &pSlot
, sal_False
,
1385 SFX_CALLMODE_MODAL
==(eCall
&SFX_CALLMODE_MODAL
) ) )
1388 if ( pArgs
&& *pArgs
)
1390 SfxAllItemSet
aSet( pShell
->GetPool() );
1391 for ( const SfxPoolItem
**pArg
= pArgs
; *pArg
; ++pArg
)
1392 MappedPut_Impl( aSet
, **pArg
);
1393 pReq
= new SfxRequest( nSlot
, eCall
, aSet
);
1396 pReq
= new SfxRequest( nSlot
, eCall
, pShell
->GetPool() );
1397 pReq
->SetModifier( nModi
);
1398 if( pInternalArgs
&& *pInternalArgs
)
1400 SfxAllItemSet
aSet( SFX_APP()->GetPool() );
1401 for ( const SfxPoolItem
**pArg
= pInternalArgs
; *pArg
; ++pArg
)
1403 pReq
->SetInternalArgs_Impl( aSet
);
1405 _Execute( *pShell
, *pSlot
, *pReq
, eCall
);
1406 const SfxPoolItem
* pRet
= pReq
->GetReturnValue();
1407 delete pReq
; return pRet
;
1412 //--------------------------------------------------------------------
1413 const SfxPoolItem
* SfxDispatcher::Execute
1415 sal_uInt16 nSlot
, // die Id der auszufuehrenden Funktion
1416 SfxCallMode eCall
, // SFX_CALLMODE_SYNCRHON, ..._ASYNCHRON oder ..._SLOT
1417 const SfxItemSet
&rArgs
// <SfxItemSet> mit Parametern
1422 Methode zum Ausf"uhren eines <SfxSlot>s "uber die Slot-Id.
1427 const SfxPoolItem* Pointer auf ein bis zum n"achsten Durchlauf
1428 der Message-Loop g"ultiges SfxPoolItem,
1429 welches den R"uckgabewert enth"alt.
1431 Oder ein 0-Pointer, wenn die Funktion nicht
1432 ausgef"uhrt wurde (z.B. Abbruch durch den
1437 return Execute( nSlot
, eCall
, 0, rArgs
);
1440 //--------------------------------------------------------------------
1441 const SfxPoolItem
* SfxDispatcher::Execute
1446 const SfxItemSet
&rArgs
1449 if ( IsLocked(nSlot
) )
1452 SfxShell
*pShell
= 0;
1453 const SfxSlot
*pSlot
= 0;
1454 if ( GetShellAndSlot_Impl( nSlot
, &pShell
, &pSlot
, sal_False
,
1455 SFX_CALLMODE_MODAL
==(eCall
&SFX_CALLMODE_MODAL
) ) )
1457 SfxAllItemSet
aSet( pShell
->GetPool() );
1458 SfxItemIter
aIter(rArgs
);
1459 for ( const SfxPoolItem
*pArg
= aIter
.FirstItem();
1461 pArg
= aIter
.NextItem() )
1462 MappedPut_Impl( aSet
, *pArg
);
1463 SfxRequest
aReq( nSlot
, eCall
, aSet
);
1464 aReq
.SetModifier( nModi
);
1465 _Execute( *pShell
, *pSlot
, aReq
, eCall
);
1466 return aReq
.GetReturnValue();
1471 //--------------------------------------------------------------------
1472 const SfxPoolItem
* SfxDispatcher::_Execute
1474 sal_uInt16 nSlot
, // die Id der auszufuehrenden Funktion
1475 SfxCallMode eCall
, // SFX_CALLMODE_SYNCRHON, ..._ASYNCHRON oder ..._SLOT
1476 va_list pVarArgs
, // Parameterliste ab 2. Parameter
1477 const SfxPoolItem
* pArg1
// erster Parameter
1482 Methode zum Ausf"uhren eines <SfxSlot>s "uber die Slot-Id.
1487 const SfxPoolItem* Pointer auf ein bis zum n"achsten Durchlauf
1488 der Message-Loop g"ultiges SfxPoolItem,
1489 welches den R"uckgabewert enth"alt.
1491 Oder ein 0-Pointer, wenn die Funktion nicht
1492 ausgef"uhrt wurde (z.B. Abbruch durch den
1497 if ( IsLocked(nSlot
) )
1500 SfxShell
*pShell
= 0;
1501 const SfxSlot
*pSlot
= 0;
1502 if ( GetShellAndSlot_Impl( nSlot
, &pShell
, &pSlot
, sal_False
,
1503 SFX_CALLMODE_MODAL
==(eCall
&SFX_CALLMODE_MODAL
) ) )
1505 SfxAllItemSet
aSet( pShell
->GetPool() );
1507 for ( const SfxPoolItem
*pArg
= pArg1
;
1509 pArg
= va_arg( pVarArgs
, const SfxPoolItem
* ) )
1510 MappedPut_Impl( aSet
, *pArg
);
1512 SfxRequest
aReq( nSlot
, eCall
, aSet
);
1513 _Execute( *pShell
, *pSlot
, aReq
, eCall
);
1514 return aReq
.GetReturnValue();
1519 //--------------------------------------------------------------------
1520 const SfxPoolItem
* SfxDispatcher::Execute
1522 sal_uInt16 nSlot
, // die Id der auszufuehrenden Funktion
1523 SfxCallMode eCall
, // SFX_CALLMODE_SYNCRHON, ..._ASYNCHRON oder ..._SLOT
1524 const SfxPoolItem
* pArg1
, // erster Parameter
1525 ... // 0-terminiertes Liste Parametern
1530 Methode zum Ausf"uhren eines <SfxSlot>s "uber die Slot-Id.
1535 Die Parameter werden kopiert, k"onnen daher als Adresse von
1536 Stack-Objekten "ubergeben werden.
1541 const SfxPoolItem* Pointer auf ein bis zum n"achsten Durchlauf
1542 der Message-Loop g"ultiges SfxPoolItem,
1543 welches den R"uckgabewert enth"alt.
1545 Oder ein 0-Pointer, wenn die Funktion nicht
1546 ausgef"uhrt wurde (z.B. Abbruch durch den
1552 pDispatcher->Execute( SID_OPENDOCUMENT, SFX_CALLMODE_SYNCHRON,
1553 &SfxStringItem( SID_FILE_NAME, "\\tmp\\temp.sdd" ),
1554 &SfxStringItem( SID_FILTER_NAME, "StarDraw Presentation" ),
1555 &SfxBoolItem( SID_DOC_READONLY, sal_False ),
1560 if ( IsLocked(nSlot
) )
1563 SfxShell
*pShell
= 0;
1564 const SfxSlot
*pSlot
= 0;
1565 if ( GetShellAndSlot_Impl( nSlot
, &pShell
, &pSlot
, sal_False
,
1566 SFX_CALLMODE_MODAL
==(eCall
&SFX_CALLMODE_MODAL
) ) )
1568 SfxAllItemSet
aSet( pShell
->GetPool() );
1571 va_start( pVarArgs
, pArg1
);
1572 for ( const SfxPoolItem
*pArg
= pArg1
;
1574 pArg
= va_arg( pVarArgs
, const SfxPoolItem
* ) )
1575 MappedPut_Impl( aSet
, *pArg
);
1578 SfxRequest
aReq( nSlot
, eCall
, aSet
);
1579 _Execute( *pShell
, *pSlot
, aReq
, eCall
);
1580 return aReq
.GetReturnValue();
1585 //--------------------------------------------------------------------
1587 IMPL_LINK( SfxDispatcher
, PostMsgHandler
, SfxRequest
*, pReq
)
1591 Hilfsmethode zum Empfangen der asynchron auszuf"uhrenden <SfxRequest>s.
1596 DBG_ASSERT( !pImp
->bFlushing
, "recursive call to dispatcher" );
1597 SFX_STACK(SfxDispatcher::PostMsgHandler
);
1599 // ist auch der Pool noch nicht gestorben?
1600 // SfxRequest* pReq = pExec->pRequest;
1601 if ( !pReq
->IsCancelled() )
1603 if ( !IsLocked(pReq
->GetSlot()) )
1607 if ( _FindServer(pReq
->GetSlot(), aSvr
, HACK(x
) sal_True
) )
1608 // SfxShell *pShell = GetShell(pExec->nLevel);
1609 // if ( pShell && pShell->GetInterface()->GetSlot( pExec->pSlot->GetSlotId() ) )
1611 const SfxSlot
*pSlot
= aSvr
.GetSlot();
1612 SfxShell
*pSh
= GetShell(aSvr
.GetShellLevel());
1614 DBG( SfxApplication
*pSfxApp
= SFX_APP() );
1615 DBG( pSfxApp
->EnterAsynchronCall_Impl() );
1617 // Wenn pSlot ein "Pseudoslot" f"ur Macros oder Verben ist, kann
1618 // er im Call_Impl zerst"ort werden, also nicht mehr benutzen!
1619 pReq
->SetSynchronCall( sal_False
);
1620 Call_Impl( *pSh
, *pSlot
, *pReq
, pReq
->AllowsRecording() ); //! woher bRecord?
1621 // Call_Impl( *pShell, *pExec->pSlot, *pReq, sal_True ); //! woher bRecord?
1622 DBG( pSfxApp
->LeaveAsynchronCall_Impl() );
1629 // pImp->xPoster->Post(pExec);
1630 if ( pImp
->bLocked
)
1631 pImp
->aReqArr
.Insert( new SfxRequest(*pReq
), pImp
->aReqArr
.Count() );
1633 pImp
->xPoster
->Post(new SfxRequest(*pReq
));
1642 //--------------------------------------------------------------------
1643 void SfxDispatcher::EnterAction( const String
& rName
)
1645 // marks the beginning of a block of actions
1650 DBG_ASSERT( pImp
->aStack
.Count() > 0, "EnterAction on empty dispatcher stack" );
1651 if ( ++pImp
->nActionLevel
== 1 )
1653 SfxUndoManager
*pUndoMgr
= GetShell(0)->GetUndoManager();
1655 pUndoMgr
->EnterListAction( rName
, rName
HACK(RepeatComment
), 0 HACK(ID
) );
1658 //--------------------------------------------------------------------
1659 void SfxDispatcher::LeaveAction()
1661 // marks the end of a block of actions
1665 DBG_ASSERT( pImp
->nActionLevel
> 0, "EnterAction without LeaveAction" );
1666 if ( --pImp
->nActionLevel
== 0 )
1668 SfxUndoManager
*pUndoMgr
= GetShell(0)->GetUndoManager();
1670 pUndoMgr
->LeaveListAction();
1674 //--------------------------------------------------------------------
1675 void SfxDispatcher::SetMenu_Impl()
1679 SfxTopViewFrame
* pTop
= PTR_CAST( SfxTopViewFrame
, pImp
->pFrame
->GetTopViewFrame() );
1680 if ( pTop
&& pTop
->GetBindings().GetDispatcher() == this )
1682 SfxTopFrame
* pFrm
= pTop
->GetTopFrame_Impl();
1683 if ( pFrm
->IsMenuBarOn_Impl() )
1685 com::sun::star::uno::Reference
< com::sun::star::beans::XPropertySet
> xPropSet( pFrm
->GetFrameInterface(), com::sun::star::uno::UNO_QUERY
);
1686 if ( xPropSet
.is() )
1688 com::sun::star::uno::Reference
< ::com::sun::star::frame::XLayoutManager
> xLayoutManager
;
1689 com::sun::star::uno::Any aValue
= xPropSet
->getPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "LayoutManager" )));
1690 aValue
>>= xLayoutManager
;
1691 if ( xLayoutManager
.is() )
1693 rtl::OUString
aMenuBarURL( RTL_CONSTASCII_USTRINGPARAM( "private:resource/menubar/menubar" ));
1694 if ( !xLayoutManager
->isElementVisible( aMenuBarURL
) )
1695 xLayoutManager
->createElement( aMenuBarURL
);
1703 //--------------------------------------------------------------------
1704 long SfxDispatcher::Update_Impl( sal_Bool bForce
)
1706 SFX_STACK(SfxDispatcher::Update_Impl
);
1710 if ( !pImp
->pFrame
|| pImp
->bUILocked
)
1713 SFX_APP(); // -Wall is this required???
1714 SfxDispatcher
*pDisp
= this;
1715 sal_Bool bUpdate
= bForce
;
1716 while ( pDisp
&& pDisp
->pImp
->pFrame
)
1718 SfxWorkWindow
*pWork
= pDisp
->pImp
->pFrame
->GetFrame()->GetWorkWindow_Impl();
1719 SfxDispatcher
*pAct
= pWork
->GetBindings().GetDispatcher_Impl();
1720 if ( pAct
== pDisp
|| pAct
== this )
1723 bUpdate
= !pDisp
->pImp
->bUpdated
;
1724 pDisp
->pImp
->bUpdated
= sal_True
;
1729 pDisp
= pDisp
->pImp
->pParent
;
1732 if ( !bUpdate
|| pImp
->pFrame
->GetFrame()->IsClosing_Impl() )
1735 SfxTopViewFrame
* pTop
= pImp
->pFrame
? PTR_CAST( SfxTopViewFrame
, pImp
->pFrame
->GetTopViewFrame() ) : NULL
;
1736 sal_Bool bUIActive
= pTop
&& pTop
->GetBindings().GetDispatcher() == this;
1738 if ( !bUIActive
&& pTop
&& GetBindings() == &pTop
->GetBindings() )
1739 // keep own tools internally for collecting
1740 GetBindings()->GetDispatcher()->pImp
->bUpdated
= sal_False
;
1742 SfxBindings
* pBindings
= GetBindings();
1744 pBindings
->DENTERREGISTRATIONS();
1746 com::sun::star::uno::Reference
< com::sun::star::frame::XFrame
> xFrame
= pBindings
->GetActiveFrame();
1747 com::sun::star::uno::Reference
< com::sun::star::beans::XPropertySet
> xPropSet( xFrame
, com::sun::star::uno::UNO_QUERY
);
1748 com::sun::star::uno::Reference
< ::com::sun::star::frame::XLayoutManager
> xLayoutManager
;
1749 if ( xPropSet
.is() )
1753 com::sun::star::uno::Any aValue
= xPropSet
->getPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "LayoutManager" )) );
1754 aValue
>>= xLayoutManager
;
1756 catch ( com::sun::star::uno::Exception
& )
1761 if ( xLayoutManager
.is() )
1762 xLayoutManager
->lock();
1764 sal_Bool bIsIPActive
= pImp
->pFrame
&& pImp
->pFrame
->GetObjectShell()->IsInPlaceActive();
1765 SfxInPlaceClient
*pClient
= pImp
->pFrame
? pImp
->pFrame
->GetViewShell()->GetUIActiveClient() : NULL
;
1766 if ( bUIActive
&& /* !bIsIPActive && */ ( !pClient
|| !pClient
->IsObjectUIActive() ) )
1769 SfxWorkWindow
*pWorkWin
= pImp
->pFrame
->GetFrame()->GetWorkWindow_Impl();
1770 SfxWorkWindow
*pTaskWin
= pImp
->pFrame
->GetTopFrame()->GetWorkWindow_Impl();
1771 pTaskWin
->ResetStatusBar_Impl();
1773 SfxDispatcher
*pDispat
= this;
1776 SfxWorkWindow
*pWork
= pDispat
->pImp
->pFrame
->GetFrame()->GetWorkWindow_Impl();
1777 SfxDispatcher
*pAct
= pWork
->GetBindings().GetDispatcher_Impl();
1778 if ( pAct
== pDispat
|| pAct
== this )
1780 pWork
->ResetObjectBars_Impl();
1781 pWork
->ResetChildWindows_Impl();
1784 pDispat
= pDispat
->pImp
->pParent
;
1787 sal_Bool bIsActive
= sal_False
;
1788 SfxDispatcher
*pActDispat
= pWorkWin
->GetBindings().GetDispatcher_Impl();
1790 while ( pActDispat
&& !bIsActive
)
1792 if ( pDispat
== pActDispat
)
1793 bIsActive
= sal_True
;
1794 pActDispat
= pActDispat
->pImp
->pParent
;
1797 _Update_Impl( bUIActive
, !bIsIPActive
, bIsIPActive
, pTaskWin
);
1798 if ( bUIActive
|| bIsActive
)
1799 pWorkWin
->UpdateObjectBars_Impl();
1802 pBindings
->DLEAVEREGISTRATIONS();
1804 if ( xLayoutManager
.is() )
1805 xLayoutManager
->unlock();
1810 sal_uInt32
SfxDispatcher::_Update_Impl( sal_Bool bUIActive
, sal_Bool bIsMDIApp
, sal_Bool bIsIPOwner
, SfxWorkWindow
*pTaskWin
)
1812 sal_uInt32 nHelpId
= 0;
1814 SfxWorkWindow
*pWorkWin
= pImp
->pFrame
->GetFrame()->GetWorkWindow_Impl();
1815 sal_Bool bIsActive
= sal_False
;
1816 sal_Bool bIsTaskActive
= sal_False
;
1817 SfxDispatcher
*pActDispat
= pWorkWin
->GetBindings().GetDispatcher_Impl();
1818 SfxDispatcher
*pDispat
= this;
1819 while ( pActDispat
&& !bIsActive
)
1821 if ( pDispat
== pActDispat
)
1822 bIsActive
= sal_True
;
1823 pActDispat
= pActDispat
->pImp
->pParent
;
1826 if ( pImp
->pParent
&& !pImp
->bQuiet
/* && bUIActive */ )
1827 nHelpId
= pImp
->pParent
->_Update_Impl( bUIActive
, bIsMDIApp
, bIsIPOwner
, pTaskWin
);
1829 for (sal_uInt16 n
=0; n
<SFX_OBJECTBAR_MAX
; n
++)
1830 pImp
->aObjBars
[n
].nResId
= 0;
1831 pImp
->aChildWins
.Remove(0, pImp
->aChildWins
.Count());
1833 // bQuiet : own shells aren't considered for UI and SlotServer
1834 // bNoUI: own Shells aren't considered fors UI
1835 if ( pImp
->bQuiet
|| pImp
->bNoUI
|| (pImp
->pFrame
&& pImp
->pFrame
->GetObjectShell()->IsPreview()) )
1838 sal_uInt32 nStatBarId
=0;
1839 SfxShell
*pStatusBarShell
= NULL
;
1841 SfxSlotPool
* pSlotPool
= &SfxSlotPool::GetSlotPool( GetFrame() );
1842 sal_uInt16 nTotCount
= pImp
->aStack
.Count();
1843 for ( sal_uInt16 nShell
= nTotCount
; nShell
> 0; --nShell
)
1845 SfxShell
*pShell
= GetShell( nShell
-1 );
1846 SfxInterface
*pIFace
= pShell
->GetInterface();
1847 if (pShell
->GetHelpId())
1848 nHelpId
= pShell
->GetHelpId();
1850 // don't consider shells if "Hidden" oder "Quiet"
1851 sal_Bool bReadOnlyShell
= IsReadOnlyShell_Impl( nShell
-1 );
1853 for ( nNo
= 0; pIFace
&& nNo
<pIFace
->GetObjectBarCount(); ++nNo
)
1855 sal_uInt16 nPos
= pIFace
->GetObjectBarPos(nNo
);
1856 if ( bReadOnlyShell
&& !( nPos
& SFX_VISIBILITY_READONLYDOC
) )
1859 // check wether toolbar needs activation of a special feature
1860 sal_uInt32 nFeature
= pIFace
->GetObjectBarFeature(nNo
);
1861 if ( nFeature
&& !pShell
->HasUIFeature( nFeature
) )
1864 // check for toolboxes that are exclusively for a viewer
1867 BOOL bViewerTbx
= SFX_VISIBILITY_VIEWER
== ( nPos
& SFX_VISIBILITY_VIEWER
);
1868 SfxObjectShell
* pSh
= pImp
->pFrame
->GetObjectShell();
1869 SFX_ITEMSET_ARG( pSh
->GetMedium()->GetItemSet(), pItem
, SfxBoolItem
, SID_VIEWONLY
, sal_False
);
1870 BOOL bIsViewer
= pItem
&& pItem
->GetValue();
1871 if ( bIsViewer
!= bViewerTbx
)
1875 // always register toolbars, allows to switch them on
1876 sal_Bool bVisible
= pIFace
->IsObjectBarVisible(nNo
);
1878 nPos
&= SFX_POSITION_MASK
;
1880 SfxObjectBars_Impl
& rBar
= pImp
->aObjBars
[nPos
& SFX_POSITION_MASK
];
1882 rBar
.nResId
= pIFace
->GetObjectBarResId(nNo
).GetId();
1883 const String
*pName
= pIFace
->GetObjectBarName(nNo
);
1885 rBar
.aName
= *pName
;
1888 rBar
.pIFace
= pIFace
;
1890 if ( bUIActive
|| bIsActive
)
1892 pWorkWin
->SetObjectBar_Impl(
1893 nPos
, rBar
.nResId
, rBar
.pIFace
, &rBar
.aName
);
1900 for ( nNo
=0; pIFace
&& nNo
<pIFace
->GetChildWindowCount(); nNo
++ )
1902 sal_uInt32 nId
= pIFace
->GetChildWindowId(nNo
);
1903 const SfxSlot
*pSlot
= pSlotPool
->GetSlot( (sal_uInt16
) nId
);
1904 DBG_ASSERT( pSlot
, "Childwindow slot missing!");
1905 if ( bReadOnlyShell
)
1907 // only show ChildWindows if their slot is allowed for readonly documents
1908 if ( pSlot
&& !pSlot
->IsMode( SFX_SLOT_READONLYDOC
) )
1912 sal_uInt32 nFeature
= pIFace
->GetChildWindowFeature(nNo
);
1913 if ( nFeature
&& !pShell
->HasUIFeature( nFeature
) )
1916 // slot decides wether a ChildWindow is shown when document is OLE server or OLE client
1917 sal_uInt16 nMode
= SFX_VISIBILITY_STANDARD
;
1920 if ( pSlot
->IsMode(SFX_SLOT_CONTAINER
) )
1922 if ( pWorkWin
->IsVisible_Impl( SFX_VISIBILITY_CLIENT
) )
1923 nMode
|= SFX_VISIBILITY_CLIENT
;
1927 if ( pWorkWin
->IsVisible_Impl( SFX_VISIBILITY_SERVER
) )
1928 nMode
|= SFX_VISIBILITY_SERVER
;
1932 if ( bUIActive
|| bIsActive
)
1933 pWorkWin
->SetChildWindowVisible_Impl( nId
, sal_True
, nMode
);
1934 if ( bUIActive
|| bIsActive
|| !pWorkWin
->IsFloating( (sal_uInt16
) ( nId
& 0xFFFF ) ) )
1935 pImp
->aChildWins
.Insert( nId
, pImp
->aChildWins
.Count());
1938 if ( bIsMDIApp
|| bIsIPOwner
)
1940 sal_uInt32 nId
= pIFace
->GetStatusBarResId().GetId();
1944 pStatusBarShell
= pShell
;
1949 for ( sal_uInt16 nPos
=0; nPos
<SFX_OBJECTBAR_MAX
; nPos
++ )
1951 SfxObjectBars_Impl
& rFixed
= pImp
->aFixedObjBars
[nPos
];
1952 if ( rFixed
.nResId
)
1954 SfxObjectBars_Impl
& rBar
= pImp
->aObjBars
[nPos
];
1956 pWorkWin
->SetObjectBar_Impl( rFixed
.nMode
,
1957 rFixed
.nResId
, rFixed
.pIFace
, &rFixed
.aName
);
1961 if ( pTaskWin
&& ( bIsMDIApp
|| bIsIPOwner
) )
1963 SfxDispatcher
*pActDispatcher
= pTaskWin
->GetBindings().GetDispatcher_Impl();
1964 SfxDispatcher
*pDispatcher
= this;
1965 while ( pActDispatcher
&& !bIsTaskActive
)
1967 if ( pDispatcher
== pActDispatcher
)
1968 bIsTaskActive
= sal_True
;
1969 pActDispatcher
= pActDispatcher
->pImp
->pParent
;
1972 if ( bIsTaskActive
&& nStatBarId
&& pImp
->pFrame
)
1974 // internal frames also may control statusbar
1975 SfxBindings
& rBindings
= pImp
->pFrame
->GetBindings();
1976 pImp
->pFrame
->GetFrame()->GetWorkWindow_Impl()->SetStatusBar_Impl( nStatBarId
, pStatusBarShell
, rBindings
);
1983 //--------------------------------------------------------------------
1984 void SfxDispatcher::FlushImpl()
1988 Hilfsmethode zum Ausf"uhren der ausstehenden Push- und Pop-Befehle.
1992 DBG_PROFSTART(SfxDispatcherFlush
);
1994 SFX_STACK(SfxDispatcher::FlushImpl
);
1996 DBG_TRACE("Flushing dispatcher!");
1999 ByteString
aMsg( "SfxDispatcher(" );
2000 aMsg
+= ByteString::CreateFromInt64( (sal_uIntPtr
) this );
2001 aMsg
+= ")::Flush()";
2004 pImp
->aTimer
.Stop();
2006 if ( pImp
->pParent
)
2007 pImp
->pParent
->Flush();
2009 // if ( pImp->bQuiet )
2012 pImp
->bFlushing
= !pImp
->bFlushing
;
2013 if ( !pImp
->bFlushing
)
2015 pImp
->bFlushing
= sal_True
;
2016 DBG_PROFSTOP(SfxDispatcherFlush
);
2018 #ifdef DBG_UTIL_MESSEHACK_AUSKOMMENT
2019 DBG_ERROR( "reentering SfxDispatcher::Flush()" );
2020 aMsg
+= " reentering, aborted";
2021 DbgTrace( aMsg
.GetBuffer() );
2026 SfxApplication
*pSfxApp
= SFX_APP();
2028 // in der 1. Runde den echten Stack 'um'bauen
2029 SfxToDoStack_Impl aToDoCopy
;
2030 sal_Bool bModify
= sal_False
;
2032 for ( nToDo
= pImp
->aToDoStack
.Count()-1; nToDo
>= 0; --nToDo
)
2036 SfxToDo_Impl
aToDo( pImp
->aToDoStack
.Top(nToDo
) );
2039 // tats"aechlich pushen
2040 DBG_ASSERT( !pImp
->aStack
.Contains( aToDo
.pCluster
),
2041 "pushed SfxShell already on stack" );
2042 pImp
->aStack
.Push( aToDo
.pCluster
);
2043 aToDo
.pCluster
->SetDisableFlags( pImp
->nDisableFlags
);
2045 // die bewegte Shell merken
2046 aToDoCopy
.Push( aToDo
);
2050 // tats"aechlich poppen
2051 SfxShell
* pPopped
= 0;
2052 FASTBOOL bFound
= sal_False
;
2055 DBG_ASSERT( pImp
->aStack
.Count(), "popping from empty stack" );
2056 pPopped
= pImp
->aStack
.Pop();
2057 pPopped
->SetDisableFlags( 0 );
2058 bFound
= pPopped
== aToDo
.pCluster
;
2060 // die bewegte Shell merken
2061 aToDoCopy
.Push( SfxToDo_Impl( sal_False
, aToDo
.bDelete
, sal_False
, *pPopped
) );
2063 while ( aToDo
.bUntil
&& !bFound
);
2064 DBG_ASSERT( bFound
, "wrong SfxShell popped" );
2068 pImp
->aToDoStack
.Clear();
2071 // ggf. Bindings invalidieren
2072 if ( !pSfxApp
->IsDowning() )
2076 pImp
->pCachedServ1
= 0;
2077 pImp
->pCachedServ2
= 0;
2080 InvalidateBindings_Impl( bModify
);
2083 pImp
->bFlushing
= sal_False
;
2084 pImp
->bUpdated
= sal_False
; // nicht nur bei bModify, falls Doc/Template-Config
2085 bFlushed
= sal_True
;
2086 DBG_TRACE("Successfully flushed dispatcher!");
2088 // in der 2. Runde die Shells aktivieren und ggf. l"oschen
2089 for ( nToDo
= aToDoCopy
.Count()-1; nToDo
>= 0; --nToDo
)
2091 SfxToDo_Impl
aToDo( aToDoCopy
.Top(nToDo
) );
2094 if ( pImp
->bActive
)
2095 aToDo
.pCluster
->DoActivate_Impl(pImp
->pFrame
, sal_True
);
2098 if ( pImp
->bActive
)
2099 aToDo
.pCluster
->DoDeactivate_Impl(pImp
->pFrame
, sal_True
);
2101 for ( nToDo
= aToDoCopy
.Count()-1; nToDo
>= 0; --nToDo
)
2103 SfxToDo_Impl
aToDo( aToDoCopy
.Top(nToDo
) );
2104 if ( aToDo
.bDelete
) delete aToDo
.pCluster
;
2106 sal_Bool bAwakeBindings
= aToDoCopy
.Count() != 0;
2107 if( bAwakeBindings
)
2110 // Wenn bei Activate/Deactivate/Delete weitere Stackbewegungen erfolgt sind :
2112 // falls jemand Push/Pop gerufen hat, wurde auch EnterReg gerufen!
2115 if( bAwakeBindings
&& GetBindings() )
2116 GetBindings()->DLEAVEREGISTRATIONS();
2117 DBG_PROFSTOP(SfxDispatcherFlush
);
2119 for (sal_uInt16 n
=0; n
<SFX_OBJECTBAR_MAX
; n
++)
2120 pImp
->aFixedObjBars
[n
].nResId
= 0;
2124 DbgTrace( aMsg
.GetBuffer() );
2128 //--------------------------------------------------------------------
2129 void SfxDispatcher::SetSlotFilter
2131 HACK(hier muss mal ein
enum rein
)
2132 sal_Bool bEnable
, /* sal_True:
2133 nur angegebene Slots enablen,
2134 alle anderen disablen
2137 die angegebenen Slots disablen,
2138 alle anderen zun"achst enablen
2140 sal_uInt16 nCount
, // Anzahl der SIDs im folgenden Array
2141 const sal_uInt16
* pSIDs
// sortiertes Array von 'nCount' SIDs
2146 Mit dieser Methode wird ein Filter gesetzt, mit dem gezielt Slots
2147 enabled bzw. disabled werden k"onnen. Das "ubergebene Array mu\s
2148 bis zum Dtor bzw. n"achsten <SetSlotFilter()> erhalten bleiben, es
2149 wird nicht vom Dispatcher gel"oscht, es kann daher static sein.
2151 In ReadOnly-Dokumenten kann man mit 'bEnable==2' quasi das ReadOnlyDoc
2152 Flag von Slots "ubersteuern, dieser werden also wieder gefunden. Auf
2153 andere Slots hat das dann keine Auswirkung.
2158 gezieltes disablen der Slots 1, 2 und 3:
2160 static sal_uInt16 __READONLY_DATA pSIDs[] = { 1, 2, 3 };
2161 pDisp->SetSlotFilter( sal_False, sizeof(pSIDs)/sizeof(sal_uInt16), pSIDs );
2163 nur die Slots 5, 6 und 7 zulassen:
2165 static sal_uInt16 __READONLY_DATA pSIDs[] = { 5, 6, 7 };
2166 pDisp->SetSlotFilter( sal_True, sizeof(pSIDs)/sizeof(sal_uInt16), pSIDs );
2170 pDisp->SetSlotFilter();
2175 // Array "uberpr"ufen
2176 for ( sal_uInt16 n
= 1; n
< nCount
; ++n
)
2177 DBG_ASSERT( pSIDs
[n
] > pSIDs
[n
-1], "SetSlotFilter: SIDs not sortet" );
2180 if ( pImp
->pFilterSIDs
)
2181 pImp
->pFilterSIDs
= 0;
2183 pImp
->bFilterEnabling
= bEnable
;
2184 pImp
->nFilterCount
= nCount
;
2185 pImp
->pFilterSIDs
= pSIDs
;
2187 GetBindings()->InvalidateAll(sal_True
);
2190 //--------------------------------------------------------------------
2192 #if defined( PM2 ) && (!defined( CSET ) && !defined ( MTW ) && !defined( WTC ))
2202 SfxCompareSIDs_Impl( const void* pSmaller
, const void* pBigger
)
2205 return ( (long) *((sal_uInt16
*)pSmaller
) ) - ( (long) *((sal_uInt16
*)pBigger
) );
2208 //--------------------------------------------------------------------
2209 sal_Bool
SfxDispatcher::IsSlotEnabledByFilter_Impl( sal_uInt16 nSID
) const
2213 Sucht 'nSID' in dem mit <SetSlotFilter()> gesetzten Filter und
2214 liefert sal_True, falls die SID erlaubt ist, bzw. sal_False, falls sie
2215 durch den Filter disabled ist.
2218 sal_Bool 0 => disabled
2220 2 => enabled even if ReadOnlyDoc
2225 if ( 0 == pImp
->nFilterCount
)
2226 // => alle SIDs erlaubt
2230 sal_Bool bFound
= 0 != bsearch( &nSID
, pImp
->pFilterSIDs
, pImp
->nFilterCount
,
2231 sizeof(sal_uInt16
), SfxCompareSIDs_Impl
);
2233 // even if ReadOnlyDoc
2234 if ( 2 == pImp
->bFilterEnabling
)
2235 return bFound
? 2 : 1;
2236 // sonst je nach Negativ/Positiv Filter
2237 return pImp
->bFilterEnabling
? bFound
: !bFound
;
2240 //--------------------------------------------------------------------
2241 sal_Bool
SfxDispatcher::_TryIntercept_Impl
2243 sal_uInt16 nSlot
, // zu suchende Slot-Id
2244 SfxSlotServer
& rServer
, // zu f"uellende <SfxSlotServer>-Instanz
2248 // Eventuell geh"ort der parent auch zu einer Komponente
2249 SfxDispatcher
*pParent
= pImp
->pParent
;
2250 sal_uInt16 nLevels
= pImp
->aStack
.Count();
2251 while ( pParent
&& pParent
->pImp
->pFrame
)
2253 if ( pParent
->pImp
->pFrame
->GetFrame()->HasComponent() )
2255 // Components d"urfen intercepten
2256 if ( pParent
->_TryIntercept_Impl( nSlot
, rServer
, sal_True
) )
2258 // Die eigenen Shells zum Shelllevel hinzuz"ahlen
2259 rServer
.SetShellLevel( rServer
.GetShellLevel() + nLevels
);
2263 // Keine weitere Interception
2267 nLevels
= nLevels
+ pParent
->pImp
->aStack
.Count();
2269 pParent
= pParent
->pImp
->pParent
;
2274 // Die ComponentViewShell befragen
2276 SfxShell
*pObjShell
= GetShell(0);
2277 SfxInterface
*pIFace
= pObjShell
->GetInterface();
2278 const SfxSlot
*pSlot
= pIFace
->GetSlot(nSlot
);
2282 rServer
.SetSlot(pSlot
);
2283 rServer
.SetShellLevel(0);
2285 String
aMsg( nSlot
);
2286 aMsg
+= " intercepted";
2287 DbgTrace( aMsg
.GetBuffer() );
2296 sal_Bool
SfxDispatcher::_FindServer
2298 sal_uInt16 nSlot
, // zu suchende Slot-Id
2299 SfxSlotServer
& rServer
, // zu f"uellnde <SfxSlotServer>-Instanz
2300 sal_Bool bModal
// trotz ModalMode
2305 Diese Hilfsmethode sucht den <Slot-Server>, der nSlot zur Zeit bedient.
2306 Als Ergebnis wird rServer entsprechend gef"ullt.
2308 Falls bekannt, kann das SfxInterface mitgegeben werden, von welchem
2309 nSlot momentan bedient wird.
2311 Vor der Suche nach nSlot wird der SfxDispatcher geflusht.
2317 Der Slot wurde gefunden, rServer ist g"ultig.
2320 Der Slot wird momentan nicht bedient, rServer
2325 SFX_STACK(SfxDispatcher::_FindServer
);
2327 // Dispatcher gelockt? (SID_BROWSE_STOP und SID_HELP_PI trotzdem durchlassen)
2328 SfxApplication
*pSfxApp
= SFX_APP();
2329 if ( IsLocked(nSlot
) )
2331 pImp
->bInvalidateOnUnlock
= sal_True
;
2335 // Anzahl der Shells auf den verkettenten Dispatchern z"ahlen
2337 sal_uInt16 nTotCount
= pImp
->aStack
.Count();
2338 if ( pImp
->pParent
)
2340 SfxDispatcher
*pParent
= pImp
->pParent
;
2343 nTotCount
= nTotCount
+ pParent
->pImp
->aStack
.Count();
2344 pParent
= pParent
->pImp
->pParent
;
2349 if ( SfxMacroConfig::IsMacroSlot( nSlot
) )
2351 const SfxMacroInfo
* pInfo
= pSfxApp
->GetMacroConfig()->GetMacroInfo(nSlot
);
2354 const SfxSlot
* pSlot
= pInfo
->GetSlot();
2357 rServer
.SetShellLevel(nTotCount
-1);
2358 rServer
.SetSlot( pSlot
);
2366 else if (nSlot
>= SID_VERB_START
&& nSlot
<= SID_VERB_END
)
2368 for ( sal_uInt16 nShell
= 0;; ++nShell
)
2370 SfxShell
*pSh
= GetShell(nShell
);
2373 if ( pSh
->ISA(SfxViewShell
) )
2375 const SfxSlot
* pSlot
= pSh
->GetVerbSlot_Impl(nSlot
);
2378 rServer
.SetShellLevel(nShell
);
2379 rServer
.SetSlot( pSlot
);
2386 // SID gegen gesetzten Filter pr"ufen
2387 sal_uInt16 nSlotEnableMode
=0;
2390 nSlotEnableMode
= IsSlotEnabledByFilter_Impl( nSlot
);
2391 if ( 0 == nSlotEnableMode
)
2395 // im Quiet-Mode nur Parent-Dispatcher
2398 if ( pImp
->pParent
)
2400 sal_Bool bRet
= pImp
->pParent
->_FindServer( nSlot
, rServer
, bModal
);
2401 rServer
.SetShellLevel
2402 ( rServer
.GetShellLevel() + pImp
->aStack
.Count() );
2409 sal_Bool bReadOnly
= ( 2 != nSlotEnableMode
&& pImp
->bReadOnly
);
2410 // ( pImp->pFrame && pImp->pFrame->GetObjectShell() );
2411 // pImp->pFrame->GetObjectShell()->IsLoading() );
2413 // durch alle Shells der verketteten Dispatchern von oben nach unten suchen
2415 String
aStack( "Stack:" );
2417 sal_uInt16 nFirstShell
= pImp
->bModal
&& !bModal
? pImp
->aStack
.Count() : 0;
2418 for ( sal_uInt16 i
= nFirstShell
; i
< nTotCount
; ++i
)
2420 SfxShell
*pObjShell
= GetShell(i
);
2421 SfxInterface
*pIFace
= pObjShell
->GetInterface();
2422 const SfxSlot
*pSlot
= pIFace
->GetSlot(nSlot
);
2424 if ( pSlot
&& pSlot
->nDisableFlags
&& ( pSlot
->nDisableFlags
& pObjShell
->GetDisableFlags() ) != 0 )
2427 if ( pSlot
&& !( pSlot
->nFlags
& SFX_SLOT_READONLYDOC
) && bReadOnly
)
2432 // Slot geh"ort zum Container?
2433 FASTBOOL bIsContainerSlot
= pSlot
->IsMode(SFX_SLOT_CONTAINER
);
2434 FASTBOOL bIsInPlace
= pImp
->pFrame
&& pImp
->pFrame
->GetObjectShell()->IsInPlaceActive();
2436 // Shell geh"ort zum Server?
2437 // AppDispatcher oder IPFrame-Dispatcher
2438 FASTBOOL bIsServerShell
= !pImp
->pFrame
|| bIsInPlace
;
2440 // Nat"urlich sind ServerShell-Slots auch ausf"uhrbar, wenn sie auf
2441 // einem Container-Dispatcher ohne IPClient ausgef"uhrt werden sollen.
2442 if ( !bIsServerShell
)
2444 SfxViewShell
*pViewSh
= pImp
->pFrame
->GetViewShell();
2445 bIsServerShell
= !pViewSh
|| !pViewSh
->GetUIActiveClient();
2448 // Shell geh"ort zum Container?
2449 // AppDispatcher oder kein IPFrameDispatcher
2450 FASTBOOL bIsContainerShell
= !pImp
->pFrame
|| !bIsInPlace
;
2451 // Shell und Slot passen zusammen
2452 if ( !( ( bIsContainerSlot
&& bIsContainerShell
) ||
2453 ( !bIsContainerSlot
&& bIsServerShell
) ) )
2460 String
aMsg( nSlot
);
2461 aMsg
+= " found in ";
2462 aMsg
+= pObjShell
->GetInterface()->GetClassName();
2463 DbgTrace( aMsg
.GetBuffer() );
2468 aStack
+= pObjShell
->GetInterface()->GetClassName();
2471 if ( pSlot
&& !IsAllowed( nSlot
) )
2478 rServer
.SetSlot(pSlot
);
2479 rServer
.SetShellLevel(i
);
2485 String
aMsg( nSlot
);
2486 aMsg
+= " not found in ";
2488 DbgTrace( aMsg
.GetBuffer() );
2493 sal_Bool
SfxDispatcher::HasSlot_Impl( sal_uInt16 nSlot
)
2496 sal_uInt16 nTotCount
= pImp
->aStack
.Count();
2498 if ( pImp
->pParent
&& !pImp
->pParent
->pImp
->pFrame
)
2500 // the last frame also uses the AppDispatcher
2501 nTotCount
= nTotCount
+ pImp
->aStack
.Count();
2504 if ( SfxMacroConfig::IsMacroSlot( nSlot
) )
2507 else if (nSlot
>= SID_VERB_START
&& nSlot
<= SID_VERB_END
)
2510 for ( sal_uInt16 nShell
= 0;; ++nShell
)
2512 SfxShell
*pSh
= GetShell(nShell
);
2515 if ( pSh
->ISA(SfxViewShell
) )
2520 // SID gegen gesetzten Filter pr"ufen
2521 sal_uInt16 nSlotEnableMode
=0;
2524 nSlotEnableMode
= IsSlotEnabledByFilter_Impl( nSlot
);
2525 if ( 0 == nSlotEnableMode
)
2529 // im Quiet-Mode nur Parent-Dispatcher
2533 sal_Bool bReadOnly
= ( 2 != nSlotEnableMode
&& pImp
->bReadOnly
);
2534 // ( pImp->pFrame && pImp->pFrame->GetObjectShell());
2535 // pImp->pFrame->GetObjectShell()->IsLoading() );
2537 for ( sal_uInt16 i
=0 ; i
< nTotCount
; ++i
)
2539 SfxShell
*pObjShell
= GetShell(i
);
2540 SfxInterface
*pIFace
= pObjShell
->GetInterface();
2541 const SfxSlot
*pSlot
= pIFace
->GetSlot(nSlot
);
2542 if ( pSlot
&& pSlot
->nDisableFlags
&& ( pSlot
->nDisableFlags
& pObjShell
->GetDisableFlags() ) != 0 )
2545 if ( pSlot
&& !( pSlot
->nFlags
& SFX_SLOT_READONLYDOC
) && bReadOnly
)
2550 // Slot geh"ort zum Container?
2551 FASTBOOL bIsContainerSlot
= pSlot
->IsMode(SFX_SLOT_CONTAINER
);
2552 FASTBOOL bIsInPlace
= pImp
->pFrame
&& pImp
->pFrame
->GetObjectShell()->IsInPlaceActive();
2554 // Shell geh"ort zum Server?
2555 // AppDispatcher oder IPFrame-Dispatcher
2556 FASTBOOL bIsServerShell
= !pImp
->pFrame
|| bIsInPlace
;
2558 // Nat"urlich sind ServerShell-Slots auch ausf"uhrbar, wenn sie auf
2559 // einem Container-Dispatcher ohne IPClient ausgef"uhrt werden sollen.
2560 if ( !bIsServerShell
)
2562 SfxViewShell
*pViewSh
= pImp
->pFrame
->GetViewShell();
2563 bIsServerShell
= !pViewSh
|| !pViewSh
->GetUIActiveClient();
2566 // Shell geh"ort zum Container?
2567 // AppDispatcher oder kein IPFrameDispatcher
2568 FASTBOOL bIsContainerShell
= !pImp
->pFrame
|| !bIsInPlace
;
2570 // Shell und Slot passen zusammen
2571 if ( !( ( bIsContainerSlot
&& bIsContainerShell
) ||
2572 ( !bIsContainerSlot
&& bIsServerShell
) ) )
2576 if ( pSlot
&& !IsAllowed( nSlot
) )
2588 //--------------------------------------------------------------------
2589 sal_Bool
SfxDispatcher::_FillState
2591 const SfxSlotServer
& rSvr
, // abzufragende <Slot-Server>
2592 SfxItemSet
& rState
, // zu f"ullendes <SfxItemSet>
2593 const SfxSlot
* pRealSlot
// ggf. der tats"achliche Slot
2598 Hilfsmethode zum Abfragen des Status des <Slot-Server>s rSvr.
2599 In rState m"ussen die gew"unschten Slots-Ids (teilweise in Which-Ids
2600 des betreffenden Pools umgewandelt) vorhanden sein.
2602 Der SfxDispatcher wird vor der Abfrage geflusht.
2606 SFX_STACK(SfxDispatcher::_FillState
);
2608 DBG_PROFSTART(SfxDispatcherFillState
);
2610 const SfxSlot
*pSlot
= rSvr
.GetSlot();
2611 if ( pSlot
&& IsLocked( pSlot
->GetSlotId() ) )
2613 pImp
->bInvalidateOnUnlock
= sal_True
;
2614 DBG_PROFSTOP(SfxDispatcherFillState
);
2620 DBG_ASSERT(bFlushed
, "Dispatcher not flushed after retrieving slot servers!");
2625 // Objekt ermitteln und Message an diesem Objekt aufrufen
2626 SfxShell
*pSh
= GetShell(rSvr
.GetShellLevel());
2627 DBG_ASSERT(pSh
, "ObjektShell nicht gefunden");
2632 pFunc
= pRealSlot
->GetStateFnc();
2634 pFunc
= pSlot
->GetStateFnc();
2636 pSh
->CallState( pFunc
, rState
);
2638 // pr"ufen, ob IDL (SlotMap) und aktuelle Items "ubereinstimmen
2639 if ( DbgIsAssertWarning() && rState
.Count() )
2641 SfxInterface
*pIF
= pSh
->GetInterface();
2642 SfxItemIter
aIter( rState
);
2643 for ( const SfxPoolItem
*pItem
= aIter
.FirstItem();
2645 pItem
= aIter
.NextItem() )
2646 if ( !IsInvalidItem(pItem
) && !pItem
->ISA(SfxVoidItem
) )
2648 sal_uInt16 nSlotId
= rState
.GetPool()->GetSlotId(pItem
->Which());
2649 if ( !pItem
->IsA(pIF
->GetSlot(nSlotId
)->GetType()->Type()) )
2651 ByteString
aMsg( "item-type unequal to IDL (=> no BASIC)" );
2652 aMsg
+= "\nwith SID: ";
2653 aMsg
+= ByteString::CreateFromInt32( nSlotId
);
2655 aMsg
+= pIF
->GetClassName();
2656 DbgOut( aMsg
.GetBuffer(), DBG_OUT_ERROR
, __FILE__
, __LINE__
);
2662 DBG_PROFSTOP(SfxDispatcherFillState
);
2666 DBG_PROFSTOP(SfxDispatcherFillState
);
2670 //--------------------------------------------------------------------
2671 const SfxPoolItem
* SfxDispatcher::_Execute( const SfxSlotServer
&rSvr
)
2675 Diese Methode f"uhrt einen Request "uber einen gecachten <Slot-Server>
2680 const SfxSlot
*pSlot
= rSvr
.GetSlot();
2681 if ( IsLocked( pSlot
->GetSlotId() ) )
2688 sal_uInt16 nSlot
= pSlot
->GetSlotId();
2689 if ( SfxMacroConfig::IsMacroSlot( nSlot
) )
2690 SFX_APP()->GetMacroConfig()->RegisterSlotId( nSlot
);
2692 if ( pSlot
->IsMode(SFX_SLOT_ASYNCHRON
) )
2695 SfxShell
*pShell
= GetShell( rSvr
.GetShellLevel() );
2696 SfxDispatcher
*pDispat
= this;
2699 sal_uInt16 nShellCount
= pDispat
->pImp
->aStack
.Count();
2700 for ( sal_uInt16 n
=0; n
<nShellCount
; n
++ )
2701 if ( pShell
== pDispat
->pImp
->aStack
.Top(n
) )
2703 pDispat
->pImp
->xPoster
->Post(
2704 new SfxRequest( pSlot
->GetSlotId(),
2705 SFX_CALLMODE_RECORD
, pShell
->GetPool() ) );
2706 // pDispat->pImp->xPoster->Post(new Executer(
2707 // new SfxRequest( pSlot->GetSlotId(),
2708 // SFX_CALLMODE_RECORD, pShell->GetPool() ),
2716 // Objekt ermitteln und Message an diesem Objekt aufrufen
2717 SfxShell
*pSh
= GetShell(rSvr
.GetShellLevel());
2718 SfxRequest
aReq( pSlot
->GetSlotId(), SFX_CALLMODE_RECORD
, pSh
->GetPool() );
2719 if ( Call_Impl( *pSh
, *pSlot
, aReq
, sal_True
) ) // von Bindings immer recorden
2720 return aReq
.GetReturnValue();
2726 //----------------------------------------------------------------------
2727 void SfxDispatcher::ExecutePopup( sal_uInt16 nConfigId
,
2728 Window
*pWin
, const Point
*pPos
,
2729 const SfxPoolItem
*, ... )
2731 ExecutePopup( nConfigId
, pWin
, pPos
);
2734 SfxPopupMenuManager
* SfxDispatcher::Popup( sal_uInt16 nConfigId
,Window
*pWin
, const Point
*pPos
)
2736 SfxDispatcher
&rDisp
= *SFX_APP()->GetDispatcher_Impl();
2737 sal_uInt16 nShLevel
= 0;
2741 if ( rDisp
.pImp
->bQuiet
)
2744 nShLevel
= rDisp
.pImp
->aStack
.Count();
2747 Window
*pWindow
= pWin
? pWin
: rDisp
.pImp
->pFrame
->GetFrame()->GetWorkWindow_Impl()->GetWindow();
2748 for ( pSh
= rDisp
.GetShell(nShLevel
); pSh
; ++nShLevel
, pSh
= rDisp
.GetShell(nShLevel
) )
2750 const ResId
& rResId
= pSh
->GetInterface()->GetPopupMenuResId();
2751 if ( ( nConfigId
== 0 && rResId
.GetId() ) || ( nConfigId
!= 0 && rResId
.GetId() == nConfigId
) )
2753 return SfxPopupMenuManager::Popup( rResId
, rDisp
.GetFrame(), pPos
? *pPos
: pWindow
->GetPointerPosPixel(), pWindow
);
2760 //----------------------------------------------------------------------
2761 void SfxDispatcher::ExecutePopup( sal_uInt16 nConfigId
, Window
*pWin
, const Point
*pPos
)
2763 SfxDispatcher
&rDisp
= *SFX_APP()->GetDispatcher_Impl();
2764 sal_uInt16 nShLevel
= 0;
2767 const SvVerbList *pVerbList = 0;
2768 sal_uInt16 nMaxShellLevel = rDisp.pImp->aStack.Count();
2769 for ( pSh = rDisp.GetShell(nShLevel);
2770 pSh && nShLevel < nMaxShellLevel ;
2771 ++nShLevel, pSh = rDisp.GetShell(nShLevel) )
2773 if ( pSh->GetVerbs() )
2775 pVerbList = pSh->GetVerbs();
2781 if ( rDisp
.pImp
->bQuiet
)
2784 nShLevel
= rDisp
.pImp
->aStack
.Count();
2787 Window
*pWindow
= pWin
? pWin
: rDisp
.pImp
->pFrame
->GetFrame()->GetWorkWindow_Impl()->GetWindow();
2788 for ( pSh
= rDisp
.GetShell(nShLevel
); pSh
; ++nShLevel
, pSh
= rDisp
.GetShell(nShLevel
) )
2790 const ResId
& rResId
= pSh
->GetInterface()->GetPopupMenuResId();
2791 if ( ( nConfigId
== 0 && rResId
.GetId() ) || ( nConfigId
!= 0 && rResId
.GetId() == nConfigId
) )
2793 //SfxPopupMenuManager aPop( rResId.GetId(), *rDisp.GetBindings() );
2794 //aPop.SetResMgr(rResId.GetResMgr());
2795 //aPop.AddClipboardFunctions();
2796 //aPop.Initialize();
2797 //if ( pVerbList && pVerbList->Count() )
2798 // aPop.InsertVerbs(pVerbList);
2799 //aPop.RemoveDisabledEntries();
2800 //aPop.Execute( pPos ? *pPos : pWindow->GetPointerPosPixel(), pWindow );
2801 SfxPopupMenuManager::ExecutePopup( rResId
, rDisp
.GetFrame(), pPos
? *pPos
: pWindow
->GetPointerPosPixel(), pWindow
);
2807 //----------------------------------------------------------------------
2808 void SfxDispatcher::ExecutePopup( const ResId
&rId
, Window
*pWin
, const Point
*pPos
)
2810 Window
*pWindow
= pWin
? pWin
: pImp
->pFrame
->GetFrame()->GetWorkWindow_Impl()->GetWindow();
2812 SfxPopupMenuManager aPop( rId, *GetBindings() );
2813 aPop.AddClipboardFunctions();
2815 aPop.RemoveDisabledEntries();
2816 aPop.Execute( pPos ? *pPos : pWindow->GetPointerPosPixel(), pWindow );
2818 SfxPopupMenuManager::ExecutePopup( rId
, GetFrame(), pPos
? *pPos
: pWindow
->GetPointerPosPixel(), pWindow
);
2821 //--------------------------------------------------------------------
2822 void SfxDispatcher::Lock( sal_Bool bLock
)
2826 Mit dieser Methode kann der SfxDispatcher gesperrt und freigegeben
2827 werden. Ein gesperrter SfxDispatcher f"uhrt keine <SfxRequest>s mehr
2828 aus und liefert keine Status-Informationen mehr. Er verh"alt sich
2829 so als w"aren alle Slots disabled.
2833 SfxBindings
* pBindings
= GetBindings();
2834 if ( !bLock
&& pImp
->bLocked
&& pImp
->bInvalidateOnUnlock
)
2837 pBindings
->InvalidateAll(sal_True
);
2838 pImp
->bInvalidateOnUnlock
= sal_False
;
2840 else if ( pBindings
)
2841 pBindings
->InvalidateAll(sal_False
);
2842 pImp
->bLocked
= bLock
;
2845 USHORT nCount
= pImp
->aReqArr
.Count();
2846 for ( USHORT i
=0; i
<nCount
; i
++ )
2847 pImp
->xPoster
->Post( pImp
->aReqArr
[i
] );
2848 pImp
->aReqArr
.Remove( 0, nCount
);
2852 sal_uInt32
SfxDispatcher::GetObjectBarId( sal_uInt16 nPos
) const
2854 return pImp
->aObjBars
[nPos
].nResId
;
2857 //--------------------------------------------------------------------
2858 void SfxDispatcher::ResetObjectBars_Impl()
2862 Mit dieser Methode werden alle Objectbar-Anforderungen, die dieser
2863 Dispatcher an das AppWindow hat, beseitigt.
2866 for (sal_uInt16 n
=0; n
<SFX_OBJECTBAR_MAX
; n
++)
2867 pImp
->aObjBars
[n
].nResId
= 0;
2868 pImp
->aChildWins
.Remove(0, pImp
->aChildWins
.Count());
2872 //--------------------------------------------------------------------
2873 void SfxDispatcher::DebugOutput_Impl() const
2877 sal_uInt16 nOld
= (sal_uInt16
) DbgGetData()->nTraceOut
;
2878 DbgGetData()->nTraceOut
= DBG_OUT_FILE
;
2881 DBG_TRACE("Flushed");
2883 DBG_TRACE("Updated");
2885 for ( sal_uInt16 nShell
= pImp
->aStack
.Count(); nShell
> 0; --nShell
)
2887 SfxShell
*pShell
= GetShell(nShell
-1);
2888 const SfxInterface
*pIFace
= pShell
->GetInterface();
2889 DBG_TRACE (pIFace
->GetClassName());
2892 DbgGetData()->nTraceOut
= nOld
;
2897 void SfxDispatcher::LockUI_Impl( sal_Bool bLock
)
2899 sal_Bool bWasLocked
= pImp
->bUILocked
;
2900 pImp
->bUILocked
= bLock
;
2901 if ( !bLock
&& bWasLocked
)
2902 Update_Impl( sal_True
);
2905 //-------------------------------------------------------------------------
2906 void SfxDispatcher::HideUI( sal_Bool bHide
)
2908 // if ( !bHide && pImp->bReadOnly )
2909 // bHide = sal_True;
2910 sal_Bool bWasHidden
= pImp
->bNoUI
;
2911 pImp
->bNoUI
= bHide
;
2914 SfxTopViewFrame
* pTop
= PTR_CAST( SfxTopViewFrame
, pImp
->pFrame
->GetTopViewFrame() );
2915 if ( pTop
&& pTop
->GetBindings().GetDispatcher() == this )
2917 SfxTopFrame
* pFrm
= pTop
->GetTopFrame_Impl();
2918 if ( pFrm
->IsMenuBarOn_Impl() )
2920 com::sun::star::uno::Reference
< com::sun::star::beans::XPropertySet
> xPropSet( pFrm
->GetFrameInterface(), com::sun::star::uno::UNO_QUERY
);
2921 if ( xPropSet
.is() )
2923 com::sun::star::uno::Reference
< ::com::sun::star::frame::XLayoutManager
> xLayoutManager
;
2924 com::sun::star::uno::Any aValue
= xPropSet
->getPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "LayoutManager" )));
2925 aValue
>>= xLayoutManager
;
2926 if ( xLayoutManager
.is() )
2927 xLayoutManager
->setVisible( !bHide
);
2933 if ( bHide
!= bWasHidden
)
2934 Update_Impl( sal_True
);
2937 void SfxDispatcher::SetReadOnly_Impl( sal_Bool bOn
)
2939 pImp
->bReadOnly
= bOn
;
2940 // pImp->bNoUI = bOn;
2943 sal_Bool
SfxDispatcher::GetReadOnly_Impl() const
2945 return pImp
->bReadOnly
;
2948 //-------------------------------------------------------------------------
2949 void SfxDispatcher::SetQuietMode_Impl( sal_Bool bOn
)
2953 Bei 'bOn' stellt sich dieser Dispatcher quasi tot und leitet alles
2954 an den Parent-Dispatcher weiter.
2959 SfxBindings
* pBindings
= GetBindings();
2961 pBindings
->InvalidateAll(sal_True
);
2964 //-------------------------------------------------------------------------
2965 void SfxDispatcher::SetModalMode_Impl( sal_Bool bOn
)
2969 Bei 'bOn' werden nur noch Slots des Parent-Dispatchers gefunden.
2974 SfxBindings
* pBindings
= GetBindings();
2976 pBindings
->InvalidateAll(sal_True
);
2979 void SfxDispatcher::SetExecuteMode( sal_uInt16 nMode
)
2981 pImp
->nStandardMode
= nMode
;
2984 SfxItemState
SfxDispatcher::QueryState( sal_uInt16 nSlot
, const SfxPoolItem
* &rpState
)
2986 SfxShell
*pShell
= 0;
2987 const SfxSlot
*pSlot
= 0;
2988 if ( GetShellAndSlot_Impl( nSlot
, &pShell
, &pSlot
, sal_False
, sal_False
) )
2990 rpState
= pShell
->GetSlotState(nSlot
);
2992 return SFX_ITEM_DISABLED
;
2994 return SFX_ITEM_AVAILABLE
;
2997 return SFX_ITEM_DISABLED
;
3000 SfxItemState
SfxDispatcher::QueryState( USHORT nSID
, ::com::sun::star::uno::Any
& rAny
)
3002 SfxShell
*pShell
= 0;
3003 const SfxSlot
*pSlot
= 0;
3004 if ( GetShellAndSlot_Impl( nSID
, &pShell
, &pSlot
, sal_False
, sal_False
) )
3006 const SfxPoolItem
* pItem( 0 );
3008 pItem
= pShell
->GetSlotState( nSID
);
3010 return SFX_ITEM_DISABLED
;
3013 ::com::sun::star::uno::Any aState
;
3014 if ( !pItem
->ISA(SfxVoidItem
) )
3017 SfxItemPool
& rPool
= pShell
->GetPool();
3018 USHORT nWhich
= rPool
.GetWhich( nSID
);
3019 if ( rPool
.GetMetric( nWhich
) == SFX_MAPUNIT_TWIP
)
3020 nSubId
|= CONVERT_TWIPS
;
3021 pItem
->QueryValue( aState
, (BYTE
)nSubId
);
3025 return SFX_ITEM_AVAILABLE
;
3029 return SFX_ITEM_DISABLED
;
3032 sal_Bool
SfxDispatcher::IsReadOnlyShell_Impl( sal_uInt16 nShell
) const
3034 sal_uInt16 nShellCount
= pImp
->aStack
.Count();
3035 if ( nShell
< nShellCount
)
3037 SfxShell
* pShell
= pImp
->aStack
.Top( nShell
);
3038 if( pShell
->ISA( SfxModule
) || pShell
->ISA( SfxApplication
) || pShell
->ISA( SfxViewFrame
) )
3041 return pImp
->bReadOnly
;
3043 else if ( pImp
->pParent
)
3044 return pImp
->pParent
->IsReadOnlyShell_Impl( nShell
- nShellCount
);
3048 // Ein dirty trick, um an die Methoden der private base class von
3049 // SfxShellStack_Impl heranzukommen
3050 class StackAccess_Impl
: public SfxShellStack_Implarr_
3053 void SfxDispatcher::InsertShell_Impl( SfxShell
& rShell
, sal_uInt16 nPos
)
3057 // Der cast geht, weil SfxShellStack_Impl keine eigenen member hat
3058 ((StackAccess_Impl
*) (&pImp
->aStack
))->Insert( nPos
, &rShell
);
3059 rShell
.SetDisableFlags( pImp
->nDisableFlags
);
3060 rShell
.DoActivate_Impl(pImp
->pFrame
, sal_True
);
3062 if ( !SFX_APP()->IsDowning() )
3064 pImp
->bUpdated
= sal_False
;
3065 pImp
->pCachedServ1
= 0;
3066 pImp
->pCachedServ2
= 0;
3067 InvalidateBindings_Impl(sal_True
);
3071 void SfxDispatcher::RemoveShell_Impl( SfxShell
& rShell
)
3075 // Der cast geht, weil SfxShellStack_Impl keine eigenen member hat
3076 StackAccess_Impl
& rStack
= *((StackAccess_Impl
*) (&pImp
->aStack
));
3077 sal_uInt16 nCount
= rStack
.Count();
3078 for ( sal_uInt16 n
=0; n
<nCount
; ++n
)
3080 if ( rStack
[n
] == &rShell
)
3083 rShell
.SetDisableFlags( 0 );
3084 rShell
.DoDeactivate_Impl(pImp
->pFrame
, sal_True
);
3089 if ( !SFX_APP()->IsDowning() )
3091 pImp
->bUpdated
= sal_False
;
3092 pImp
->pCachedServ1
= 0;
3093 pImp
->pCachedServ2
= 0;
3094 InvalidateBindings_Impl(sal_True
);
3098 sal_Bool
SfxDispatcher::IsAllowed
3104 Die Methode prueft, ob der Zugriff auf diese Schnittstelle erlaubt ist.
3107 if ( !pImp
->pDisableList
)
3112 // BinSearch in der DisableListe
3113 SvUShorts
& rList
= *pImp
->pDisableList
;
3114 sal_uInt16 nCount
= rList
.Count();
3115 sal_uInt16 nLow
= 0, nMid
= 0, nHigh
;
3116 sal_Bool bFound
= sal_False
;
3119 while ( !bFound
&& nLow
<= nHigh
)
3121 nMid
= (nLow
+ nHigh
) >> 1;
3122 DBG_ASSERT( nMid
< nCount
, "bsearch ist buggy" );
3124 int nDiff
= (int) nSlot
- (int) rList
[nMid
];
3131 else if ( nDiff
> 0 )
3142 // Slot in der Liste gefunden ?
3143 sal_uInt16 nPos
= bFound
? nMid
: nLow
;
3145 DBG_ASSERT( nPos
<= nCount
, "" );
3146 DBG_ASSERT( nPos
== nCount
|| nSlot
<= rList
[nPos
], "" );
3147 DBG_ASSERT( nPos
== 0 || nSlot
> rList
[nPos
-1], "" );
3148 DBG_ASSERT( ( (nPos
+1) >= nCount
) || nSlot
< rList
[nPos
+1], "" );
3154 void SfxDispatcher::InvalidateBindings_Impl( sal_Bool bModify
)
3157 if ( IsAppDispatcher() )
3159 for ( SfxViewFrame
*pFrame
= SfxViewFrame::GetFirst();
3161 pFrame
= SfxViewFrame::GetNext( *pFrame
) )
3162 pFrame
->GetBindings().InvalidateAll(bModify
);
3164 // alle Bindings sind betroffen
3165 for ( SfxInPlaceFrame *pIPFrame = (SfxInPlaceFrame*)
3166 SfxViewFrame::GetFirst(0, TYPE(SfxInPlaceFrame));
3168 pIPFrame = (SfxInPlaceFrame*)
3169 SfxViewFrame::GetNext(*pIPFrame, 0, TYPE(SfxInPlaceFrame)) )
3170 pIPFrame->GetBindings().InvalidateAll(bModify);
3172 for ( SfxPlugInFrame *pPIFrame = (SfxPlugInFrame*)
3173 SfxViewFrame::GetFirst(0, TYPE(SfxPlugInFrame));
3175 pPIFrame = (SfxPlugInFrame*)
3176 SfxViewFrame::GetNext(*pPIFrame, 0, TYPE(SfxPlugInFrame)) )
3177 pPIFrame->GetBindings().InvalidateAll(bModify);
3179 for ( SfxTask* pTask = SfxTask::GetFirst(); pTask;
3180 pTask = SfxTask::GetNext( *pTask ) )
3181 if ( !pTask->IsExternal() )
3182 pTask->GetBindings()->InvalidateAll(bModify);
3187 SfxDispatcher
*pDisp
= GetBindings()->GetDispatcher_Impl();
3190 if ( pDisp
== this )
3192 GetBindings()->InvalidateAll( bModify
);
3196 pDisp
= pDisp
->pImp
->pParent
;
3201 sal_Bool
SfxDispatcher::IsUpdated_Impl() const
3203 return pImp
->bUpdated
;
3206 void SfxDispatcher::SetDisableFlags( sal_uInt32 nFlags
)
3208 pImp
->nDisableFlags
= nFlags
;
3209 for ( int i
= int(pImp
->aStack
.Count()) - 1; i
>= 0; --i
)
3210 pImp
->aStack
.Top( (sal_uInt16
) i
)->SetDisableFlags( nFlags
);
3213 sal_uInt32
SfxDispatcher::GetDisableFlags() const
3215 return pImp
->nDisableFlags
;