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