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 102 SfxToDo_Impl() 103 : pCluster(0) 104 , bPush(false) 105 , bDelete(false) 106 , bUntil(false) 107 {} 108 SfxToDo_Impl( bool bOpPush, bool bOpDelete, bool bOpUntil, SfxShell& rCluster ) 109 : pCluster(&rCluster) 110 , bPush(bOpPush) 111 , bDelete(bOpDelete) 112 , bUntil(bOpUntil) 113 {} 114 ~SfxToDo_Impl(){} 115 116 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 130 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 //==================================================================== 181 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 //-------------------------------------------------------------------- 202 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 //-------------------------------------------------------------------- 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 //==================================================================== 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 376 SfxDispatcher::SfxDispatcher( SfxDispatcher* pParent ) 377 { 378 Construct_Impl( pParent ); 379 pImp->pFrame = 0; 380 } 381 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 //==================================================================== 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 //==================================================================== 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 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 } 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 //-------------------------------------------------------------------- 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 //-------------------------------------------------------------------- 678 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 //-------------------------------------------------------------------- 702 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 //-------------------------------------------------------------------- 723 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 //-------------------------------------------------------------------- 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 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 //-------------------------------------------------------------------- 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 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 //-------------------------------------------------------------------- 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 //-------------------------------------------------------------------- 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 //-------------------------------------------------------------------- 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 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 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 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 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 //-------------------------------------------------------------------- 1215 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 //-------------------------------------------------------------------- 1228 SfxPoolItem* SfxExecuteItem::Clone( SfxItemPool* ) const 1229 { 1230 return new SfxExecuteItem( *this ); 1231 } 1232 1233 //-------------------------------------------------------------------- 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 //-------------------------------------------------------------------- 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 //-------------------------------------------------------------------- 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 //-------------------------------------------------------------------- 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 //-------------------------------------------------------------------- 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 //-------------------------------------------------------------------- 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 //-------------------------------------------------------------------- 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 //-------------------------------------------------------------------- 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 //-------------------------------------------------------------------- 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 //-------------------------------------------------------------------- 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 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 //-------------------------------------------------------------------- 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 //-------------------------------------------------------------------- 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 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 wether 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 wether 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 //-------------------------------------------------------------------- 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 //-------------------------------------------------------------------- 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 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 //-------------------------------------------------------------------- 2136 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 //-------------------------------------------------------------------- 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 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 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 //-------------------------------------------------------------------- 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 //-------------------------------------------------------------------- 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 //---------------------------------------------------------------------- 2629 void SfxDispatcher::ExecutePopup( sal_uInt16 nConfigId, 2630 Window *pWin, const Point *pPos, 2631 const SfxPoolItem *, ... ) 2632 { 2633 ExecutePopup( nConfigId, pWin, pPos ); 2634 } 2635 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 //---------------------------------------------------------------------- 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 //---------------------------------------------------------------------- 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 //-------------------------------------------------------------------- 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 2754 sal_uInt32 SfxDispatcher::GetObjectBarId( sal_uInt16 nPos ) const 2755 { 2756 return pImp->aObjBars[nPos].nResId; 2757 } 2758 2759 //-------------------------------------------------------------------- 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 //-------------------------------------------------------------------- 2775 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 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 //------------------------------------------------------------------------- 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 2839 void SfxDispatcher::SetReadOnly_Impl( sal_Bool bOn ) 2840 { 2841 pImp->bReadOnly = bOn; 2842 // pImp->bNoUI = bOn; 2843 } 2844 2845 sal_Bool SfxDispatcher::GetReadOnly_Impl() const 2846 { 2847 return pImp->bReadOnly; 2848 } 2849 2850 //------------------------------------------------------------------------- 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 //------------------------------------------------------------------------- 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 2881 void SfxDispatcher::SetExecuteMode( sal_uInt16 nMode ) 2882 { 2883 pImp->nStandardMode = nMode; 2884 } 2885 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 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 2934 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 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 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 3000 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 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 3082 sal_Bool SfxDispatcher::IsUpdated_Impl() const 3083 { 3084 return pImp->bUpdated; 3085 } 3086 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 3094 sal_uInt32 SfxDispatcher::GetDisableFlags() const 3095 { 3096 return pImp->nDisableFlags; 3097 } 3098 3099 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