LCOV - code coverage report
Current view: top level - sfx2/source/control - dispatch.cxx (source / functions) Hit Total Coverage
Test: commit 10e77ab3ff6f4314137acd6e2702a6e5c1ce1fae Lines: 702 914 76.8 %
Date: 2014-11-03 Functions: 58 71 81.7 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2             : /*
       3             :  * This file is part of the LibreOffice project.
       4             :  *
       5             :  * This Source Code Form is subject to the terms of the Mozilla Public
       6             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       7             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
       8             :  *
       9             :  * This file incorporates work covered by the following license notice:
      10             :  *
      11             :  *   Licensed to the Apache Software Foundation (ASF) under one or more
      12             :  *   contributor license agreements. See the NOTICE file distributed
      13             :  *   with this work for additional information regarding copyright
      14             :  *   ownership. The ASF licenses this file to you under the Apache
      15             :  *   License, Version 2.0 (the "License"); you may not use this file
      16             :  *   except in compliance with the License. You may obtain a copy of
      17             :  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
      18             :  */
      19             : 
      20             : #include <config_features.h>
      21             : 
      22             : #include <algorithm>
      23             : #include <deque>
      24             : #include <vector>
      25             : 
      26             : #include <stdarg.h>
      27             : #include <stdio.h>
      28             : #include <stdlib.h>
      29             : 
      30             : #include <com/sun/star/beans/XPropertySet.hpp>
      31             : #include <com/sun/star/frame/XDispatchRecorderSupplier.hpp>
      32             : #include <com/sun/star/frame/XLayoutManager.hpp>
      33             : 
      34             : #include <rtl/strbuf.hxx>
      35             : #include <sfx2/app.hxx>
      36             : #include <sfx2/bindings.hxx>
      37             : #include <sfx2/childwin.hxx>
      38             : #include <sfx2/dispatch.hxx>
      39             : #include <sfx2/docfac.hxx>
      40             : #include <sfx2/docfile.hxx>
      41             : #include <sfx2/hintpost.hxx>
      42             : #include <sfx2/ipclient.hxx>
      43             : #include <sfx2/mnumgr.hxx>
      44             : #include <sfx2/module.hxx>
      45             : #include <sfx2/msg.hxx>
      46             : #include <sfx2/msgpool.hxx>
      47             : #include <sfx2/objface.hxx>
      48             : #include <sfx2/request.hxx>
      49             : #include <sfx2/sfxhelp.hxx>
      50             : #include <sfx2/sfxuno.hxx>
      51             : #include <sfx2/viewfrm.hxx>
      52             : #include <sfx2/viewsh.hxx>
      53             : #include <svl/eitem.hxx>
      54             : #include <svl/intitem.hxx>
      55             : #include <svl/itemiter.hxx>
      56             : #include <svl/itempool.hxx>
      57             : #include <svl/undo.hxx>
      58             : #include <svl/whiter.hxx>
      59             : #include <svtools/helpopt.hxx>
      60             : #include <vcl/wrkwin.hxx>
      61             : 
      62             : #include <appdata.hxx>
      63             : #include <sfxtypes.hxx>
      64             : #include <slotserv.hxx>
      65             : #include <workwin.hxx>
      66             : 
      67             : typedef std::vector<SfxShell*> SfxShellStack_Impl;
      68             : 
      69             : typedef std::vector<SfxRequest*> SfxRequestPtrArray;
      70             : 
      71             : struct SfxToDo_Impl
      72             : {
      73             :     SfxShell*  pCluster;
      74             :     bool       bPush;
      75             :     bool       bDelete;
      76             :     bool       bDeleted;
      77             :     bool       bUntil;
      78             : 
      79       93781 :     SfxToDo_Impl( bool bOpPush, bool bOpDelete, bool bOpUntil, SfxShell& rCluster )
      80             :         : pCluster(&rCluster)
      81             :         , bPush(bOpPush)
      82             :         , bDelete(bOpDelete)
      83             :         , bDeleted(false)
      84       93781 :         , bUntil(bOpUntil)
      85       93781 :                 {}
      86             : };
      87             : 
      88      147732 : struct SfxObjectBars_Impl
      89             : {
      90             :     sal_uInt32     nResId;  // Resource - and ConfigId of the Toolbox
      91             :     sal_uInt16     nMode;   // special visibility flags
      92             :     OUString       aName;
      93             :     SfxInterface*  pIFace;
      94             : 
      95      151294 :     SfxObjectBars_Impl() : nResId(0), nMode(0), pIFace(NULL) {}
      96             : };
      97             : 
      98        5819 : struct SfxDispatcher_Impl
      99             : {
     100             :     //When the dispatched is locked, SfxRequests accumulate in aReqArr for
     101             :     //later dispatch when unlocked via Post
     102             : 
     103             :     //The pointers are typically deleted in Post, only if we never get around
     104             :     //to posting them do we delete the unposted requests.
     105             :     SfxRequestPtrArray aReqArr;
     106        5682 :     ~SfxDispatcher_Impl()
     107        5682 :     {
     108        5682 :         for (SfxRequestPtrArray::iterator aI = aReqArr.begin(), aEnd = aReqArr.end(); aI != aEnd; ++aI)
     109           0 :             delete *aI;
     110        5682 :     }
     111             :     const SfxSlotServer* pCachedServ1;  // last called message
     112             :     const SfxSlotServer* pCachedServ2;  // penultimate called Message
     113             :     SfxShellStack_Impl   aStack;        // active functionality
     114             :     Timer                aTimer;        // for Flush
     115             :     std::deque<SfxToDo_Impl> aToDoStack;    // not processed Push/Pop
     116             :     SfxViewFrame*        pFrame;        // NULL or associated Frame
     117             :     SfxDispatcher*       pParent;       // AppDispatcher, NULL if possible
     118             :     SfxHintPosterRef     xPoster;       // Execute asynchronous
     119             :     bool                 bFlushing;     // sal_True during Flush //?
     120             :     bool                 bUpdated;      // Update_Impl has run
     121             :     bool                 bLocked;       // No Execute
     122             :     bool                 bInvalidateOnUnlock;   // because someone asked
     123             :     bool                 bActive;       // not to be confused with set!
     124             :     bool*                pInCallAliveFlag;   // view the Destructor Stack
     125             :     SfxObjectBars_Impl   aObjBars[SFX_OBJECTBAR_MAX];
     126             :     SfxObjectBars_Impl   aFixedObjBars[SFX_OBJECTBAR_MAX];
     127             :     std::vector<sal_uInt32> aChildWins;
     128             :     sal_uInt32           nEventId;      // EventId UserEvent
     129             :     bool                 bNoUI;         // UI only from Parent Dispatcher
     130             :     bool                 bReadOnly;     // Document is ReadOnly
     131             :     bool                 bQuiet;        // Only use parent dispatcher
     132             :     bool                 bModal;        // Only slots from parent dispatcher
     133             : 
     134             :     SfxSlotFilterState   nFilterEnabling; // 1==filter enabled slots,
     135             :                                           // 2==ReadOnlyDoc overturned
     136             :     sal_uInt16           nFilterCount;  // Number of SIDs in pFilterSIDs
     137             :     const sal_uInt16*    pFilterSIDs;   // sorted Array of SIDs
     138             :     sal_uInt32           nDisableFlags;
     139             :     bool                 bFlushed;
     140             :     std::deque< std::deque<SfxToDo_Impl> > aToDoCopyStack;
     141             : };
     142             : 
     143             : #define SFX_FLUSH_TIMEOUT    50
     144             : 
     145             : /** This method checks if the stack of the SfxDispatchers is flushed, or if
     146             :     push- or pop- commands are pending.
     147             : */
     148        1564 : bool SfxDispatcher::IsFlushed() const
     149             : {
     150        1564 :      return pImp->bFlushed;
     151             : }
     152             : 
     153             : /** This method performs outstanding push- and pop- commands. For <SfxShell>s,
     154             :     which are new on the stack, the <SfxShell::Activate(bool)> is invoked
     155             :     with bMDI == sal_True, for SfxShells that are removed from the stack, the
     156             :     <SfxShell::Deactivate(bool)> is invoked with bMDI == sal_True
     157             : */
     158      501716 : void SfxDispatcher::Flush()
     159             : {
     160      501716 :     if (!pImp->bFlushed) FlushImpl();
     161      501716 : }
     162             : 
     163             : /** With this method, a <SfxShell> pushed on to the SfxDispatcher.
     164             :     The SfxShell is first marked for push and a timer is set up.
     165             :     First when the timer has couted down to zero the push
     166             :     ( <SfxDispatcher::Flush()> ) is actually performed and the
     167             :     <SfxBindings> is invalidated. While the timer is counting down
     168             :     the opposing push and pop commands on the same SfxShell are
     169             :     leveled out.
     170             : */
     171       44707 : void SfxDispatcher::Push(SfxShell& rShell)
     172             : 
     173             : {
     174       44707 :     Pop( rShell, SFX_SHELL_PUSH );
     175       44707 : }
     176             : 
     177             : /** This method checks whether a particular <SfxShell> instance is
     178             :     on the SfxDispatcher.
     179             : 
     180             :     @returns sal_True   The SfxShell instance is on the SfxDispatcher.
     181             :              sal_False  The SfxShell instance is not on the SfxDispatcher.
     182             : */
     183        4572 : bool SfxDispatcher::IsActive(const SfxShell& rShell)
     184             : 
     185             : {
     186        4572 :     return CheckVirtualStack(rShell, true);
     187             : }
     188             : 
     189             : /** With this method it can be determined whether the SfxDispatcher is
     190             :     locked or unlocked. A locked SfxDispatcher does not perform <SfxRequest>s
     191             :     and no longer provides any status information. It behaves as if all the
     192             :     slots are disabled.
     193             : 
     194             :     The dispatcher is also marked as blocked, if all Dispatcher are locked
     195             :     (<SfxApplication::LockDispatcher()>) or the associated top frame is in the
     196             :     modal-mode and if the specified slot are handled as frame-specific
     197             :     (ie, not served by the application).
     198             : */
     199      315056 : bool SfxDispatcher::IsLocked(sal_uInt16) const
     200             : {
     201      315056 :     return pImp->bLocked;
     202             : }
     203             : 
     204             : /** With this method it can be determined if the SfxDispacher is the
     205             :     applications dispatcher.
     206             : 
     207             :     @return bool it is the application dispatcher.
     208             : */
     209       46122 : bool SfxDispatcher::IsAppDispatcher() const
     210             : {
     211       46122 :     return !pImp->pFrame;
     212             : }
     213             : 
     214             : /** Helper function to check whether a slot can be executed and
     215             :     check the execution itself
     216             : */
     217        1090 : int SfxDispatcher::Call_Impl(SfxShell& rShell, const SfxSlot &rSlot, SfxRequest &rReq, bool bRecord)
     218             : {
     219             :     SFX_STACK(SfxDispatcher::Call_Impl);
     220             : 
     221             :     // The slot may be called (meaning enabled)
     222        1090 :     if ( rSlot.IsMode(SFX_SLOT_FASTCALL) || rShell.CanExecuteSlot_Impl(rSlot) )
     223             :     {
     224        1090 :         if ( GetFrame() )
     225             :         {
     226             :             // Recording may start
     227             :             com::sun::star::uno::Reference< com::sun::star::frame::XFrame > xFrame(
     228        1090 :                     GetFrame()->GetFrame().GetFrameInterface(),
     229        1090 :                     com::sun::star::uno::UNO_QUERY);
     230             : 
     231             :             com::sun::star::uno::Reference< com::sun::star::beans::XPropertySet > xSet(
     232             :                     xFrame,
     233        2180 :                     com::sun::star::uno::UNO_QUERY);
     234             : 
     235        1090 :             if ( xSet.is() )
     236             :             {
     237        1090 :                 com::sun::star::uno::Any aProp = xSet->getPropertyValue("DispatchRecorderSupplier");
     238        2180 :                 com::sun::star::uno::Reference< com::sun::star::frame::XDispatchRecorderSupplier > xSupplier;
     239        2180 :                 com::sun::star::uno::Reference< com::sun::star::frame::XDispatchRecorder > xRecorder;
     240        1090 :                 aProp >>= xSupplier;
     241        1090 :                 if(xSupplier.is())
     242           2 :                     xRecorder = xSupplier->getDispatchRecorder();
     243             : 
     244        1090 :                 if ( bRecord && xRecorder.is() && !rSlot.IsMode(SFX_SLOT_NORECORD) )
     245        1092 :                     rReq.Record_Impl( rShell, rSlot, xRecorder, GetFrame() );
     246        1090 :             }
     247             :         }
     248             :         // Get all that is needed, because the slot may not have survived the
     249             :         // Execute if it is a 'pseudo slot' for macros or verbs.
     250        1090 :         bool bAutoUpdate = rSlot.IsMode(SFX_SLOT_AUTOUPDATE);
     251             : 
     252             :         // API-call parentheses and document-lock during the calls
     253             :         {
     254             :             // 'this' must respond in the Destructor
     255        1090 :             bool bThisDispatcherAlive = true;
     256        1090 :             bool *pOldInCallAliveFlag = pImp->pInCallAliveFlag;
     257        1090 :             pImp->pInCallAliveFlag = &bThisDispatcherAlive;
     258             : 
     259        1090 :             SfxExecFunc pFunc = rSlot.GetExecFnc();
     260        1090 :             rShell.CallExec( pFunc, rReq );
     261             : 
     262             :             // If 'this' is still alive
     263        1090 :             if ( bThisDispatcherAlive )
     264        1090 :                 pImp->pInCallAliveFlag = pOldInCallAliveFlag;
     265             :             else
     266             :             {
     267           0 :                 if ( pOldInCallAliveFlag )
     268             :                 {
     269             :                     // also protect nested stack frames
     270           0 :                     *pOldInCallAliveFlag = false;
     271             :                 }
     272             : 
     273             :                 // do nothing after this object is dead
     274           0 :                 return rReq.IsDone() ? 1 : 0;
     275             :             }
     276             :         }
     277             : 
     278        1090 :         if ( rReq.IsDone() )
     279             :         {
     280         467 :             SfxBindings *pBindings = GetBindings();
     281             : 
     282             :             // When AutoUpdate update immediately; "Pseudoslots" must not be
     283             :             // Autoupdate!
     284         467 :             if ( bAutoUpdate && pBindings )
     285             :             {
     286         238 :                 const SfxSlot* pSlave = rSlot.GetLinkedSlot();
     287         238 :                 if (pSlave)
     288             :                 {
     289             :                     // When enum slots take any bound slave slot
     290           0 :                     while (!pBindings->IsBound(pSlave->GetSlotId()) && pSlave != &rSlot )
     291           0 :                         pSlave = pSlave->GetLinkedSlot();
     292           0 :                     pBindings->Invalidate(pSlave->GetSlotId());
     293           0 :                     pBindings->Update(pSlave->GetSlotId());
     294             :                 }
     295             :                 else
     296             :                 {
     297         238 :                     pBindings->Invalidate(rSlot.GetSlotId());
     298         238 :                     pBindings->Update(rSlot.GetSlotId());
     299             :                 }
     300             :             }
     301             : 
     302         467 :             return sal_True;
     303             :         }
     304             :     }
     305             : 
     306         623 :     return sal_False;
     307             : }
     308             : 
     309        5819 : void SfxDispatcher::Construct_Impl( SfxDispatcher* pParent )
     310             : {
     311        5819 :     pImp.reset(new SfxDispatcher_Impl);
     312        5819 :     pImp->bFlushed = true;
     313             : 
     314        5819 :     pImp->pCachedServ1 = 0;
     315        5819 :     pImp->pCachedServ2 = 0;
     316        5819 :     pImp->bFlushing = false;
     317        5819 :     pImp->bUpdated = false;
     318        5819 :     pImp->bLocked = false;
     319        5819 :     pImp->bActive = false;
     320        5819 :     pImp->pParent = NULL;
     321        5819 :     pImp->bNoUI = false;
     322        5819 :     pImp->bReadOnly = false;
     323        5819 :     pImp->bQuiet = false;
     324        5819 :     pImp->bModal = false;
     325        5819 :     pImp->pInCallAliveFlag = 0;
     326        5819 :     pImp->nFilterEnabling = SFX_SLOT_FILTER_DISABLED;
     327        5819 :     pImp->nFilterCount = 0;
     328        5819 :     pImp->pFilterSIDs = 0;
     329        5819 :     pImp->nDisableFlags = 0;
     330             : 
     331        5819 :     pImp->pParent = pParent;
     332             : 
     333        5819 :     pImp->bInvalidateOnUnlock = false;
     334             : 
     335       81466 :     for (sal_uInt16 n=0; n<SFX_OBJECTBAR_MAX; n++)
     336       75647 :         pImp->aObjBars[n].nResId = 0;
     337             : 
     338        5819 :     GenLink aGenLink( LINK(this, SfxDispatcher, PostMsgHandler) );
     339             : 
     340        5819 :     pImp->xPoster = new SfxHintPoster(aGenLink);
     341             : 
     342        5819 :     pImp->aTimer.SetTimeout(SFX_FLUSH_TIMEOUT);
     343        5819 :     pImp->aTimer.SetTimeoutHdl( LINK(this, SfxDispatcher, EventHdl_Impl ) );
     344        5819 : }
     345             : 
     346         303 : SfxDispatcher::SfxDispatcher( SfxDispatcher* pParent )
     347             : {
     348         303 :     Construct_Impl( pParent );
     349         303 :     pImp->pFrame = 0;
     350         303 : }
     351             : 
     352             : /** The constructor of the SfxDispatcher class places a stack of empty
     353             :     <SfxShell> pointers. It is not initially locked and is considered flushed.
     354             : */
     355        5516 : SfxDispatcher::SfxDispatcher(SfxViewFrame *pViewFrame)
     356             : {
     357        5516 :     if ( pViewFrame )
     358             :     {
     359        5516 :         SfxViewFrame *pFrame = pViewFrame->GetParentViewFrame();
     360        5516 :         if ( pFrame )
     361           0 :             Construct_Impl(  pFrame->GetDispatcher() );
     362             :         else
     363        5516 :             Construct_Impl( 0 );
     364             :     }
     365             :     else
     366           0 :         Construct_Impl( 0 );
     367        5516 :     pImp->pFrame = pViewFrame;
     368        5516 : }
     369             : 
     370             : /** The destructor of the SfxDispatcher class should not be called when the
     371             :     SfxDispatcher instance is active. It may, however, still be a <SfxShell>
     372             :     pointer on the stack.
     373             : */
     374       17046 : SfxDispatcher::~SfxDispatcher()
     375             : {
     376             : #ifdef DBG_UTIL
     377             :     OStringBuffer sTemp("Delete Dispatcher ");
     378             :     sTemp.append(reinterpret_cast<sal_Int64>(this));
     379             :     OSL_TRACE("%s", sTemp.getStr());
     380             :     DBG_ASSERT( !pImp->bActive, "deleting active Dispatcher" );
     381             : #endif
     382             : 
     383             :     // So that no timer by Reschedule in PlugComm strikes the LeaveRegistrations
     384        5682 :     pImp->aTimer.Stop();
     385        5682 :     pImp->xPoster->SetEventHdl( Link() );
     386             : 
     387             :     // Notify the stack varialbles in Call_Impl
     388        5682 :     if ( pImp->pInCallAliveFlag )
     389           0 :         *pImp->pInCallAliveFlag = false;
     390             : 
     391             :     // Get bindings and application
     392        5682 :     SfxApplication *pSfxApp = SfxGetpApp();
     393        5682 :     SfxBindings* pBindings = GetBindings();
     394             : 
     395             :     // When not flushed, revive the bindings
     396        5682 :     if (pBindings && !pSfxApp->IsDowning() && !pImp->bFlushed)
     397        5506 :         pBindings->DLEAVEREGISTRATIONS();
     398             : 
     399             :     // may unregister the bindings
     400       16886 :     while ( pBindings )
     401             :     {
     402        5522 :         if ( pBindings->GetDispatcher_Impl() == this)
     403        5514 :             pBindings->SetDispatcher(0);
     404        5522 :         pBindings = pBindings->GetSubBindings_Impl();
     405             :     }
     406       11364 : }
     407             : 
     408             : /** With this method, one or more <SfxShell> are poped from the SfxDispatcher.
     409             :     The SfxShell is marked for popping and a timer is set up. Only when the
     410             :     timer has reached the end, the pop is actually performed
     411             :     ( <SfxDispatcher::Flush()> ) and the <SfxBindings> is invalidated.
     412             :     While the timer is running the opposing push and pop commands on one
     413             :     SfxShell cancel each other out.
     414             : 
     415             :     @param rShell the stack to take the SfxShell instance.
     416             :     @param nMode SFX_SHELL_POP_UNTIL
     417             :                             Also all 'rShell' of SfxShells are taken from the
     418             :                             stack.
     419             : 
     420             :                  SFX_SHELL_POP_DELETE
     421             :                             All SfxShells actually taken from the stack
     422             :                             will be deleted.
     423             : 
     424             :                  SFX_SHELL_PUSH (InPlace use only)
     425             :                             The Shell is pushed.
     426             : */
     427       66849 : void SfxDispatcher::Pop(SfxShell& rShell, sal_uInt16 nMode)
     428             : {
     429             :     DBG_ASSERT( rShell.GetInterface(),
     430             :                 "pushing SfxShell without previous RegisterInterface()" );
     431             : 
     432       66849 :     bool bDelete = (nMode & SFX_SHELL_POP_DELETE) == SFX_SHELL_POP_DELETE;
     433       66849 :     bool bUntil = (nMode & SFX_SHELL_POP_UNTIL) == SFX_SHELL_POP_UNTIL;
     434       66849 :     bool bPush = (nMode & SFX_SHELL_PUSH) == SFX_SHELL_PUSH;
     435             : 
     436       66849 :     SfxApplication *pSfxApp = SfxGetpApp();
     437             : 
     438             :     SAL_INFO(
     439             :         "sfx.control",
     440             :         "-SfxDispatcher(" << this << (bPush ? ")::Push(" : ")::Pop(")
     441             :             << (rShell.GetInterface()
     442             :                 ? rShell.GetInterface()->GetClassName() : SAL_STREAM(&rShell))
     443             :             << (bDelete ? ") with delete" : ")")
     444             :             << (bUntil ? " (up to)" : ""));
     445             : 
     446             :     // same shell as on top of the to-do stack?
     447       66849 :     if(pImp->aToDoStack.size() && pImp->aToDoStack.front().pCluster == &rShell)
     448             :     {
     449             :         // cancel inverse actions
     450          46 :         if ( pImp->aToDoStack.front().bPush != bPush )
     451          46 :             pImp->aToDoStack.pop_front();
     452             :         else
     453             :         {
     454             :             DBG_ASSERT( bPush, "SfxInterface pushed more than once" );
     455             :             DBG_ASSERT( !bPush, "SfxInterface popped more than once" );
     456             :         }
     457             :     }
     458             :     else
     459             :     {
     460             :         // Remember Action
     461       66803 :         pImp->aToDoStack.push_front( SfxToDo_Impl(bPush, bDelete, bUntil, rShell) );
     462       66803 :         if (pImp->bFlushed)
     463             :         {
     464             :             OSL_TRACE("Unflushed dispatcher!");
     465       33761 :             pImp->bFlushed = false;
     466       33761 :             pImp->bUpdated = false;
     467             : 
     468             :             // Put bindings to sleep
     469       33761 :             SfxBindings* pBindings = GetBindings();
     470       33761 :             if ( pBindings )
     471       33290 :                 pBindings->DENTERREGISTRATIONS();
     472             :         }
     473             :     }
     474             : 
     475       66849 :     if(!pSfxApp->IsDowning() && !pImp->aToDoStack.empty())
     476             :     {
     477             :         // No immediate update is requested
     478       66849 :         pImp->aTimer.SetTimeout(SFX_FLUSH_TIMEOUT);
     479       66849 :         pImp->aTimer.SetTimeoutHdl( LINK(this, SfxDispatcher, EventHdl_Impl ) );
     480       66849 :         pImp->aTimer.Start();
     481             :     }
     482             :     else
     483             :     {
     484             :         // but to do nothing
     485           0 :         pImp->aTimer.Stop();
     486             : 
     487             :         // Bindings may wake up again
     488           0 :         if(pImp->aToDoStack.empty())
     489             :         {
     490           0 :             SfxBindings* pBindings = GetBindings();
     491           0 :             if ( pBindings )
     492           0 :                 pBindings->DLEAVEREGISTRATIONS();
     493             :         }
     494             :     }
     495       66849 : }
     496             : 
     497             : 
     498             : /** This handler is called after <SfxDispatcher::Invalidate()> or after
     499             :     changes on the stack (<SfxDispatcher::Push()> and <SfxDispatcher::Pop())
     500             : 
     501             :     It flushes the Stack, if it is dirty, thus it actually excecutes the
     502             :     pending Push and Pop commands.
     503             : */
     504           0 : IMPL_LINK_INLINE_START( SfxDispatcher, EventHdl_Impl, void *, pvoid )
     505             : {
     506             :     (void)pvoid; // unused
     507             : 
     508           0 :     Flush();
     509           0 :     Update_Impl();
     510           0 :     SfxBindings* pBindings = GetBindings();
     511           0 :     if ( pBindings )
     512           0 :         pBindings->StartUpdate_Impl(false);
     513           0 :     return 0;
     514             : }
     515           0 : IMPL_LINK_INLINE_END( SfxDispatcher, EventHdl_Impl, void *, pvoid )
     516             : 
     517             : /** With this method it can be tested whether the <SfxShell> rShell is on the
     518             :     stack, when it was flushed. This way the SfxDispatcher is not actually
     519             :     flushed.
     520             : 
     521             :     This method is intended among other things to make assertions possible
     522             :     without the side effect of having to flush the SfxDispathcer.
     523             : */
     524        4572 : bool SfxDispatcher::CheckVirtualStack(const SfxShell& rShell, bool bDeep)
     525             : {
     526             :     SFX_STACK(SfxDispatcher::CheckVirtualStack);
     527             : 
     528        4572 :     SfxShellStack_Impl aStack( pImp->aStack );
     529        4572 :     for(std::deque<SfxToDo_Impl>::reverse_iterator i = pImp->aToDoStack.rbegin(); i != pImp->aToDoStack.rend(); ++i)
     530             :     {
     531           0 :         if(i->bPush)
     532           0 :             aStack.push_back(i->pCluster);
     533             :         else
     534             :         {
     535           0 :             SfxShell* pPopped(NULL);
     536           0 :             do
     537             :             {
     538             :                 DBG_ASSERT( !aStack.empty(), "popping from empty stack" );
     539           0 :                 pPopped = aStack.back();
     540           0 :                 aStack.pop_back();
     541             :             }
     542           0 :             while(i->bUntil && pPopped != i->pCluster);
     543             :             DBG_ASSERT(pPopped == i->pCluster, "popping unpushed SfxInterface");
     544             :         }
     545             :     }
     546             : 
     547             :     bool bReturn;
     548        4572 :     if ( bDeep )
     549        4572 :         bReturn = std::find(aStack.begin(), aStack.end(), &rShell) != aStack.end();
     550             :     else
     551           0 :         bReturn = aStack.back() == &rShell;
     552        4572 :     return bReturn;
     553             : }
     554             : 
     555             : /** Determines the position of a given SfxShell in the stack of the dispatcher.
     556             :     If possible this is flushed before.
     557             : 
     558             :     [Return value]
     559             : 
     560             :     sal_uInt16                  == USRT_MAX
     561             :                                 The SfxShell is not on this SfxDispatcher.
     562             : 
     563             :                                 < USHRT_MAX
     564             :                                 Position of the SfxShell on the Dispatcher
     565             :                                 from the top count stating with 0.
     566             : */
     567        6075 : sal_uInt16 SfxDispatcher::GetShellLevel(const SfxShell& rShell)
     568             : {
     569             :     SFX_STACK(SfxDispatcher::GetShellLevel);
     570        6075 :     Flush();
     571             : 
     572       21158 :     for ( sal_uInt16 n = 0; n < pImp->aStack.size(); ++n )
     573       21158 :         if ( *( pImp->aStack.rbegin() + n ) == &rShell )
     574        6075 :             return n;
     575           0 :     if ( pImp->pParent )
     576             :     {
     577           0 :         sal_uInt16 nRet = pImp->pParent->GetShellLevel(rShell);
     578           0 :         if ( nRet == USHRT_MAX )
     579           0 :             return nRet;
     580           0 :         return  nRet + pImp->aStack.size();
     581             :     }
     582             : 
     583           0 :     return USHRT_MAX;
     584             : }
     585             : 
     586             : /** Returns a pointer to the <SfxShell> which is at the position nIdx
     587             :     (from the top, last pushed is 0) on the stack.
     588             : 
     589             :     Thus the SfxDispatcher is not flushed.
     590             : 
     591             :     Is the stack not deep enough a NULL-Pointer is returned.
     592             : */
     593      920745 : SfxShell *SfxDispatcher::GetShell(sal_uInt16 nIdx) const
     594             : {
     595      920745 :     sal_uInt16 nShellCount = pImp->aStack.size();
     596      920745 :     if ( nIdx < nShellCount )
     597      920745 :         return *(pImp->aStack.rbegin() + nIdx);
     598           0 :     else if ( pImp->pParent )
     599           0 :         return pImp->pParent->GetShell( nIdx - nShellCount );
     600           0 :     return 0;
     601             : }
     602             : 
     603             : /** This method returns a pointer to the <SfxBinding> Instance on which the
     604             :     SfxDispatcher is curretly bound. A SfxDispatcher is only bound to
     605             :     the SfxBindings when it is <UI-aktiv>. If it is not UI-active,
     606             :     a NULL-pointer is returned.
     607             : 
     608             :     The returned pointer is only valid in the immediate context of the method
     609             :     call.
     610             : */
     611      230621 : SfxBindings* SfxDispatcher::GetBindings() const
     612             : {
     613      230621 :     if ( pImp->pFrame )
     614      229208 :         return &pImp->pFrame->GetBindings();
     615             :     else
     616        1413 :         return NULL;
     617             : }
     618             : 
     619             : /** Returns a pointer to the <SfxViewFrame> instance, which belongs to
     620             :     this SfxDispatcher. If it is about the application dispatcher,
     621             :     a NULL-pointer is returned.
     622             : */
     623      533694 : SfxViewFrame* SfxDispatcher::GetFrame() const
     624             : {
     625      533694 :     return pImp->pFrame;
     626             : }
     627             : 
     628             : /** This method controls the activation of a dispatcher.
     629             : 
     630             :     Since the application dispatcher is always active, either as a sub
     631             :     dispatcher of the <SfxViewFrame> dispatcher or as itself, it is never
     632             :     activated as a whole, instead only its individual <SfxShell>s at
     633             :     <SfxDispatcher::Push(SfxShell&)>.
     634             : 
     635             :     When activating a SfxDispatcher all of the SfxShells located on its stack
     636             :     are called with the handler <SfxShell::Activate(bool)>, starting with
     637             :     the lowest.
     638             : */
     639        5741 : void SfxDispatcher::DoActivate_Impl(bool bMDI, SfxViewFrame* /* pOld */)
     640             : {
     641             :     SFX_STACK(SfxDispatcher::DoActivate);
     642        5741 :     if ( bMDI )
     643             :     {
     644             : #ifdef DBG_UTIL
     645             :         OStringBuffer sTemp("Activate Dispatcher ");
     646             :         sTemp.append(reinterpret_cast<sal_Int64>(this));
     647             :         OSL_TRACE("%s", sTemp.getStr());
     648             :         DBG_ASSERT( !pImp->bActive, "Activation error" );
     649             : #endif
     650        5741 :         pImp->bActive = true;
     651        5741 :         pImp->bUpdated = false;
     652        5741 :         SfxBindings* pBindings = GetBindings();
     653        5741 :         if ( pBindings )
     654             :         {
     655        5438 :             pBindings->SetDispatcher(this);
     656        5438 :             pBindings->SetActiveFrame( pImp->pFrame->GetFrame().GetFrameInterface() );
     657             :         }
     658             :     }
     659             :     else
     660             :     {
     661             : #ifdef DBG_UTIL
     662             :         OStringBuffer sTemp("Non-MDI-Activate Dispatcher");
     663             :         sTemp.append(reinterpret_cast<sal_Int64>(this));
     664             :         OSL_TRACE("%s", sTemp.getStr());
     665             : #endif
     666             :     }
     667             : 
     668        5741 :     if ( IsAppDispatcher() )
     669        6044 :         return;
     670             : 
     671       34602 :     for ( int i = int(pImp->aStack.size()) - 1; i >= 0; --i )
     672       29164 :         (*(pImp->aStack.rbegin() + i ))->DoActivate_Impl(pImp->pFrame, bMDI);
     673             : 
     674        5438 :     if ( bMDI && pImp->pFrame )
     675             :     {
     676        5438 :         SfxBindings *pBind = GetBindings();
     677       16314 :         while ( pBind )
     678             :         {
     679        5438 :             pBind->HidePopupCtrls_Impl( false );
     680        5438 :             pBind = pBind->GetSubBindings_Impl();
     681             :         }
     682             : 
     683        5438 :         pImp->pFrame->GetFrame().GetWorkWindow_Impl()->HidePopups_Impl( false, false, 1 );
     684             :     }
     685             : 
     686        5438 :     if(!pImp->aToDoStack.empty())
     687             :     {
     688             :         // No immediate update is requested
     689           0 :         pImp->aTimer.SetTimeout(SFX_FLUSH_TIMEOUT);
     690           0 :         pImp->aTimer.SetTimeoutHdl( LINK(this, SfxDispatcher, EventHdl_Impl ) );
     691           0 :         pImp->aTimer.Start();
     692             :     }
     693             : }
     694             : 
     695           0 : void SfxDispatcher::DoParentActivate_Impl()
     696             : {
     697           0 :     for ( int i = int(pImp->aStack.size()) - 1; i >= 0; --i )
     698           0 :         (*(pImp->aStack.rbegin() + i ))->ParentActivate();
     699           0 : }
     700             : 
     701             : /** This method controls the deactivation of a dispatcher.
     702             : 
     703             :     Since the application dispatcher is always active, either as a sub
     704             :     dispatcher of the <SfxViewFrame> dispatcher or as itself, it is never
     705             :     deactivated as a whole, instead only its individual <SfxShell>s at
     706             :     <SfxDispatcher::Pop(SfxShell&)>.
     707             : 
     708             :     When deactivating a SfxDispatcher all of the SfxShells located on its stack
     709             :     are called with the handler <SfxShell::Deactivate(bool)>, starting with
     710             :     the lowest.
     711             : */
     712        5606 : void SfxDispatcher::DoDeactivate_Impl(bool bMDI, SfxViewFrame* pNew)
     713             : {
     714             :     SFX_STACK(SfxDispatcher::DoDeactivate);
     715             : 
     716        5606 :     SfxApplication *pSfxApp = SfxGetpApp();
     717             : 
     718        5606 :     if ( bMDI )
     719             :     {
     720             :         OSL_TRACE(OStringBuffer("Deactivate Dispatcher").append(reinterpret_cast<sal_Int64>(this)).getStr());
     721             :         DBG_ASSERT( pImp->bActive, "Deactivate error" );
     722        5606 :         pImp->bActive = false;
     723             : 
     724        5606 :         if ( pImp->pFrame && !(pImp->pFrame->GetObjectShell()->IsInPlaceActive() ) )
     725             :         {
     726        5438 :             SfxWorkWindow *pWorkWin = pImp->pFrame->GetFrame().GetWorkWindow_Impl();
     727        5438 :             if ( pWorkWin )
     728             :             {
     729      199258 :                 for (size_t n=0; n<pImp->aChildWins.size();)
     730             :                 {
     731      188382 :                     SfxChildWindow *pWin = pWorkWin->GetChildWindow_Impl( (sal_uInt16) ( pImp->aChildWins[n] & 0xFFFF ) );
     732      188382 :                     if (!pWin || (pWin && pWin->GetAlignment() == SFX_ALIGN_NOALIGNMENT))
     733      188306 :                         pImp->aChildWins.erase(pImp->aChildWins.begin()+n);
     734             :                     else
     735          76 :                         n++;
     736             :                 }
     737             :             }
     738             :         }
     739             :     }
     740             :     else {
     741             :         OSL_TRACE(OStringBuffer("Non-MDI-DeActivate Dispatcher").append(reinterpret_cast<sal_Int64>(this)).getStr());
     742             :     }
     743             : 
     744        5606 :     if ( IsAppDispatcher() && !pSfxApp->IsDowning() )
     745        5606 :         return;
     746             : 
     747       48254 :     for ( sal_uInt16 i = 0; i < pImp->aStack.size(); ++i )
     748       42648 :         (*(pImp->aStack.rbegin() + i))->DoDeactivate_Impl(pImp->pFrame, bMDI);
     749             : 
     750        5606 :     bool bHidePopups = bMDI && pImp->pFrame;
     751        5606 :     if ( pNew && pImp->pFrame )
     752             :     {
     753             :         com::sun::star::uno::Reference< com::sun::star::frame::XFrame > xOldFrame(
     754          34 :             pNew->GetFrame().GetFrameInterface()->getCreator(), com::sun::star::uno::UNO_QUERY );
     755             : 
     756             :         com::sun::star::uno::Reference< com::sun::star::frame::XFrame > xMyFrame(
     757          68 :             GetFrame()->GetFrame().GetFrameInterface(), com::sun::star::uno::UNO_QUERY );
     758             : 
     759          34 :         if ( xOldFrame == xMyFrame )
     760          34 :             bHidePopups = false;
     761             :     }
     762             : 
     763        5606 :     if ( bHidePopups )
     764             :     {
     765        5438 :         SfxBindings *pBind = GetBindings();
     766       16314 :         while ( pBind )
     767             :         {
     768        5438 :             pBind->HidePopupCtrls_Impl( true );
     769        5438 :             pBind = pBind->GetSubBindings_Impl();
     770             :         }
     771             : 
     772        5438 :         pImp->pFrame->GetFrame().GetWorkWindow_Impl()->HidePopups_Impl( true, false, 1 );
     773             :     }
     774             : 
     775        5606 :     Flush();
     776             : }
     777             : 
     778           0 : void SfxDispatcher::DoParentDeactivate_Impl()
     779             : {
     780           0 :     for ( int i = int(pImp->aStack.size()) - 1; i >= 0; --i )
     781           0 :         (*(pImp->aStack.rbegin() + i))->ParentDeactivate();
     782           0 : }
     783             : 
     784             : /** This method searches in SfxDispatcher after <SfxShell> , from the Slot Id
     785             :     nSlot currently being handled. For this, the dispatcher is first flushed.
     786             : 
     787             :     @param nSlot the searchable Slot-Id
     788             :     @param ppShell the SfxShell, which are currently handled the nSlot
     789             :     @param ppSlot the SfxSlot, which are currently handled the nSlot
     790             : 
     791             :     @return int      sal_True
     792             :                      The SfxShell was found, ppShell and ppSlot are valid.
     793             : 
     794             :                      sal_False
     795             :                      The SfxShell was not found, ppShell and ppSlot are invalid.
     796             : */
     797      152131 : int SfxDispatcher::GetShellAndSlot_Impl(sal_uInt16 nSlot, SfxShell** ppShell,
     798             :         const SfxSlot** ppSlot, bool bOwnShellsOnly, bool bModal, bool bRealSlot)
     799             : {
     800             :     SFX_STACK(SfxDispatcher::GetShellAndSlot_Impl);
     801             : 
     802      152131 :     Flush();
     803      152131 :     SfxSlotServer aSvr;
     804      152131 :     if ( _FindServer(nSlot, aSvr, bModal) )
     805             :     {
     806      147689 :         if ( bOwnShellsOnly && aSvr.GetShellLevel() >= pImp->aStack.size() )
     807           0 :             return sal_False;
     808             : 
     809      147689 :         *ppShell = GetShell(aSvr.GetShellLevel());
     810      147689 :         *ppSlot = aSvr.GetSlot();
     811      147689 :         if ( 0 == (*ppSlot)->GetExecFnc() && bRealSlot )
     812           0 :             *ppSlot = (*ppShell)->GetInterface()->GetRealSlot(*ppSlot);
     813             :         // Check only real slots as enum slots don't have an execute function!
     814      147689 :         if ( bRealSlot && ((0 == *ppSlot) || (0 == (*ppSlot)->GetExecFnc()) ))
     815           0 :             return sal_False;
     816             : 
     817      147689 :         return sal_True;
     818             :     }
     819             : 
     820        4442 :     return sal_False;
     821             : }
     822             : 
     823             : /** This method performs a request for a cached <Slot-Server>.
     824             : 
     825             :     @param rShell to the calling <SfxShell>
     826             :     @param rSlot to the calling <SfxSlot>
     827             :     @param rReq function to be performed (Id and optional parameters)
     828             :     @param eCallMode Synchronously, asynchronously or as shown in the slot
     829             : */
     830        1679 : void SfxDispatcher::_Execute(SfxShell& rShell, const SfxSlot& rSlot,
     831             :         SfxRequest& rReq, SfxCallMode eCallMode)
     832             : {
     833             :     DBG_ASSERT( !pImp->bFlushing, "recursive call to dispatcher" );
     834             :     DBG_ASSERT( pImp->aToDoStack.empty(), "unprepared InPlace _Execute" );
     835             : 
     836        1679 :     if ( IsLocked( rSlot.GetSlotId() ) )
     837           0 :         return;
     838             : 
     839        3378 :     if ( bool(eCallMode & SfxCallMode::ASYNCHRON) ||
     840         636 :          ( (eCallMode & SfxCallMode::SYNCHRON) == SfxCallMode::SLOT &&
     841         296 :            rSlot.IsMode(SFX_SLOT_ASYNCHRON) ) )
     842             :     {
     843        1359 :         SfxDispatcher *pDispat = this;
     844        2718 :         while ( pDispat )
     845             :         {
     846        1359 :             sal_uInt16 nShellCount = pDispat->pImp->aStack.size();
     847        1461 :             for ( sal_uInt16 n=0; n<nShellCount; n++ )
     848             :             {
     849        1461 :                 if ( &rShell == *(pDispat->pImp->aStack.rbegin() + n) )
     850             :                 {
     851        1359 :                     if ( bool(eCallMode & SfxCallMode::RECORD) )
     852        1339 :                         rReq.AllowRecording( true );
     853        1359 :                     pDispat->pImp->xPoster->Post(new SfxRequest(rReq));
     854        1359 :                     return;
     855             :                 }
     856             :             }
     857             : 
     858           0 :             pDispat = pDispat->pImp->pParent;
     859             :         }
     860             :     }
     861             :     else
     862         320 :         Call_Impl( rShell, rSlot, rReq, SfxCallMode::RECORD==(eCallMode&SfxCallMode::RECORD) );
     863             : }
     864             : 
     865             : /** Helper function to put from rItem below the Which-ID in the pool of the
     866             :     Item Sets rSet.
     867             : */
     868        1015 : void MappedPut_Impl(SfxAllItemSet &rSet, const SfxPoolItem &rItem)
     869             : {
     870             :     // Put with mapped Which-Id if possible
     871        1015 :     const SfxItemPool *pPool = rSet.GetPool();
     872        1015 :     sal_uInt16 nWhich = rItem.Which();
     873        1015 :     if ( SfxItemPool::IsSlot(nWhich) )
     874        1015 :         nWhich = pPool->GetWhich(nWhich);
     875        1015 :     rSet.Put( rItem, nWhich );
     876        1015 : }
     877             : 
     878        4619 : const SfxSlot* SfxDispatcher::GetSlot( const OUString& rCommand )
     879             : {
     880             :     // Count the number of Shells on the linked Dispatcher
     881        4619 :     Flush();
     882        4619 :     sal_uInt16 nTotCount = pImp->aStack.size();
     883        4619 :     if ( pImp->pParent )
     884             :     {
     885           0 :         SfxDispatcher *pParent = pImp->pParent;
     886           0 :         while ( pParent )
     887             :         {
     888           0 :             nTotCount = nTotCount + pParent->pImp->aStack.size();
     889           0 :             pParent = pParent->pImp->pParent;
     890             :         }
     891             :     }
     892             : 
     893        4619 :     const SfxSlot *pSlot=NULL;
     894        4619 :     sal_uInt16 nFirstShell = 0;
     895        9107 :     for ( sal_uInt16 i = nFirstShell; i < nTotCount; ++i )
     896             :     {
     897        4619 :         SfxShell *pObjShell = GetShell(i);
     898        4619 :         SfxInterface *pIFace = pObjShell->GetInterface();
     899        4619 :         pSlot = pIFace->GetSlot( rCommand );
     900        4619 :         if ( pSlot )
     901         131 :             return pSlot;
     902             :     }
     903             : 
     904        4488 :     return 0;
     905             : }
     906             : 
     907         246 : const SfxPoolItem* SfxDispatcher::Execute(sal_uInt16 nSlot, SfxCallMode nCall,
     908             :         SfxItemSet* pArgs, SfxItemSet* pInternalArgs, sal_uInt16 nModi)
     909             : {
     910         246 :     if ( IsLocked(nSlot) )
     911           0 :         return 0;
     912             : 
     913         246 :     SfxShell *pShell = 0;
     914         246 :     const SfxSlot *pSlot = 0;
     915         246 :     if ( GetShellAndSlot_Impl( nSlot,  &pShell, &pSlot, false,
     916         246 :                                SfxCallMode::MODAL==(nCall&SfxCallMode::MODAL) ) )
     917             :     {
     918         246 :         SfxAllItemSet aSet( pShell->GetPool() );
     919         246 :         if ( pArgs )
     920             :         {
     921         246 :             SfxItemIter aIter(*pArgs);
     922         492 :             for ( const SfxPoolItem *pArg = aIter.FirstItem();
     923             :                 pArg;
     924             :                 pArg = aIter.NextItem() )
     925         492 :                 MappedPut_Impl( aSet, *pArg );
     926             :         }
     927         492 :         SfxRequest aReq( nSlot, nCall, aSet );
     928         246 :         if (pInternalArgs)
     929         246 :             aReq.SetInternalArgs_Impl( *pInternalArgs );
     930         246 :         aReq.SetModifier( nModi );
     931             : 
     932         246 :         _Execute( *pShell, *pSlot, aReq, nCall );
     933         492 :         return aReq.GetReturnValue();
     934             :     }
     935           0 :     return 0;
     936             : }
     937             : 
     938             : /** Method to excecute a <SfxSlot>s over the Slot-Id.
     939             : 
     940             :     @param nSlot the Id of the executing function
     941             :     @param eCall SfxCallMode::SYNCRHON, ..._ASYNCHRON or ..._SLOT
     942             :     @param pArgs Zero teminated C-Array of Parameters
     943             :     @param pInternalArgs Zero terminated C-Array of Parameters
     944             : 
     945             :     @return const SfxPoolItem* Pointer to the SfxPoolItem valid to the next run
     946             :                             though the Message-Loop, which contains the return
     947             :                             value.
     948             : 
     949             :                             Or a NULL-Pointer, when the function was not
     950             :                             executed (for example canceled by the user).
     951             : */
     952         932 : const SfxPoolItem* SfxDispatcher::Execute(sal_uInt16 nSlot, SfxCallMode eCall,
     953             :         const SfxPoolItem **pArgs, sal_uInt16 nModi, const SfxPoolItem **pInternalArgs)
     954             : {
     955         932 :     if ( IsLocked(nSlot) )
     956           0 :         return 0;
     957             : 
     958         932 :     SfxShell *pShell = 0;
     959         932 :     const SfxSlot *pSlot = 0;
     960         932 :     if ( GetShellAndSlot_Impl( nSlot,  &pShell, &pSlot, false,
     961         932 :                                SfxCallMode::MODAL==(eCall&SfxCallMode::MODAL) ) )
     962             :     {
     963             :         SfxRequest* pReq;
     964         612 :         if ( pArgs && *pArgs )
     965             :         {
     966           0 :             SfxAllItemSet aSet( pShell->GetPool() );
     967           0 :             for ( const SfxPoolItem **pArg = pArgs; *pArg; ++pArg )
     968           0 :                 MappedPut_Impl( aSet, **pArg );
     969           0 :             pReq = new SfxRequest( nSlot, eCall, aSet );
     970             :         }
     971             :         else
     972         612 :             pReq =  new SfxRequest( nSlot, eCall, pShell->GetPool() );
     973         612 :         pReq->SetModifier( nModi );
     974         612 :         if( pInternalArgs && *pInternalArgs)
     975             :         {
     976           0 :             SfxAllItemSet aSet( SfxGetpApp()->GetPool() );
     977           0 :             for ( const SfxPoolItem **pArg = pInternalArgs; *pArg; ++pArg )
     978           0 :                 aSet.Put( **pArg );
     979           0 :             pReq->SetInternalArgs_Impl( aSet );
     980             :         }
     981         612 :         _Execute( *pShell, *pSlot, *pReq, eCall );
     982         612 :         const SfxPoolItem* pRet = pReq->GetReturnValue();
     983         612 :         delete pReq; return pRet;
     984             :     }
     985         320 :     return 0;
     986             : }
     987             : 
     988             : /** Method to excecute a <SfxSlot>s over the Slot-Id.
     989             : 
     990             :     @param nSlot the Id of the executing function
     991             :     @param eCall SfxCallMode::SYNCRHON, ..._ASYNCHRON or ..._SLOT
     992             :     @param rArgs <SfxItemSet> with the parameters
     993             : 
     994             :     @return const SfxPoolItem* Pointer to the SfxPoolItem valid to the next run
     995             :                             though the Message-Loop, which contains the return
     996             :                             value.
     997             : 
     998             :                             Or a NULL-Pointer, when the function was not
     999             :                             executed (for example canceled by the user).
    1000             : */
    1001          22 : const SfxPoolItem* SfxDispatcher::Execute(sal_uInt16 nSlot, SfxCallMode eCall,
    1002             :         const SfxItemSet &rArgs)
    1003             : {
    1004          22 :     return Execute( nSlot, eCall, 0, rArgs );
    1005             : }
    1006             : 
    1007          22 : const SfxPoolItem* SfxDispatcher::Execute(sal_uInt16 nSlot, SfxCallMode eCall,
    1008             :         sal_uInt16 nModi, const SfxItemSet &rArgs)
    1009             : {
    1010          22 :     if ( IsLocked(nSlot) )
    1011           0 :         return 0;
    1012             : 
    1013          22 :     SfxShell *pShell = 0;
    1014          22 :     const SfxSlot *pSlot = 0;
    1015          22 :     if ( GetShellAndSlot_Impl( nSlot,  &pShell, &pSlot, false,
    1016          22 :                                SfxCallMode::MODAL==(eCall&SfxCallMode::MODAL) ) )
    1017             :     {
    1018          22 :         SfxAllItemSet aSet( pShell->GetPool() );
    1019          44 :         SfxItemIter aIter(rArgs);
    1020          44 :         for ( const SfxPoolItem *pArg = aIter.FirstItem();
    1021             :               pArg;
    1022             :               pArg = aIter.NextItem() )
    1023          22 :             MappedPut_Impl( aSet, *pArg );
    1024          44 :         SfxRequest aReq( nSlot, eCall, aSet );
    1025          22 :         aReq.SetModifier( nModi );
    1026          22 :         _Execute( *pShell, *pSlot, aReq, eCall );
    1027          44 :         return aReq.GetReturnValue();
    1028             :     }
    1029           0 :     return 0;
    1030             : }
    1031             : 
    1032             : /** Method to excecute a <SfxSlot>s over the Slot-Id.
    1033             : 
    1034             :     [Note]
    1035             : 
    1036             :     The parameters are copied, can therefore be passed on as the address
    1037             :     of stack objects.
    1038             : 
    1039             :     @param nSlot the Id of the executing function
    1040             :     @param eCall SfxCallMode::SYNCRHON, ..._ASYNCHRON or ..._SLOT
    1041             :     @param pArg1 First parameter
    1042             :     @param ... Zero terminated list of parameters
    1043             : 
    1044             :     @return                 Pointer to the SfxPoolItem valid to the next run
    1045             :                             though the Message-Loop, which contains the return
    1046             :                             value.
    1047             : 
    1048             :                             Or a NULL-Pointer, when the function was not
    1049             :                             executed (for example canceled by the user).
    1050             : 
    1051             :     [Example]
    1052             : 
    1053             :     pDispatcher->Execute( SID_OPENDOCUMENT, SfxCallMode::SYNCHRON,
    1054             :         &SfxStringItem( SID_FILE_NAME, "\\tmp\\temp.sdd" ),
    1055             :         &SfxStringItem( SID_FILTER_NAME, "StarDraw Presentation" ),
    1056             :         &SfxBoolItem( SID_DOC_READONLY, sal_False ),
    1057             :         0L );
    1058             : */
    1059        1095 : const SfxPoolItem* SfxDispatcher::Execute(sal_uInt16 nSlot, SfxCallMode eCall,
    1060             :         const SfxPoolItem*  pArg1, ...)
    1061             : {
    1062        1095 :     if ( IsLocked(nSlot) )
    1063           0 :         return 0;
    1064             : 
    1065        1095 :     SfxShell *pShell = 0;
    1066        1095 :     const SfxSlot *pSlot = 0;
    1067        1095 :     if ( GetShellAndSlot_Impl( nSlot, &pShell, &pSlot, false,
    1068        1095 :                                SfxCallMode::MODAL==(eCall&SfxCallMode::MODAL) ) )
    1069             :     {
    1070         747 :        SfxAllItemSet aSet( pShell->GetPool() );
    1071             : 
    1072             :        va_list pVarArgs;
    1073         747 :        va_start( pVarArgs, pArg1 );
    1074        2241 :        for ( const SfxPoolItem *pArg = pArg1;
    1075             :              pArg;
    1076         747 :              pArg = va_arg( pVarArgs, const SfxPoolItem* ) )
    1077         747 :            MappedPut_Impl( aSet, *pArg );
    1078         747 :        va_end(pVarArgs);
    1079             : 
    1080        1494 :        SfxRequest aReq( nSlot, eCall, aSet );
    1081         747 :        _Execute( *pShell, *pSlot, aReq, eCall );
    1082        1494 :        return aReq.GetReturnValue();
    1083             :     }
    1084         348 :     return 0;
    1085             : }
    1086             : 
    1087             : /** Helper method to receive the asynchronously executed <SfxRequest>s.
    1088             : */
    1089        1540 : IMPL_LINK(SfxDispatcher, PostMsgHandler, SfxRequest*, pReq)
    1090             : {
    1091             :     DBG_ASSERT( !pImp->bFlushing, "recursive call to dispatcher" );
    1092             :     SFX_STACK(SfxDispatcher::PostMsgHandler);
    1093             : 
    1094             :     // Has also the Pool not yet died?
    1095         770 :     if ( !pReq->IsCancelled() )
    1096             :     {
    1097         770 :         if ( !IsLocked(pReq->GetSlot()) )
    1098             :         {
    1099         770 :             Flush();
    1100         770 :             SfxSlotServer aSvr;
    1101         770 :             if ( _FindServer(pReq->GetSlot(), aSvr, true ) ) // HACK(x), whatever that was supposed to mean
    1102             :             {
    1103         770 :                 const SfxSlot *pSlot = aSvr.GetSlot();
    1104         770 :                 SfxShell *pSh = GetShell(aSvr.GetShellLevel());
    1105             : 
    1106             :                 // When the pSlot is a "Pseudoslot" for macros or Verbs, it can
    1107             :                 // be destroyed in the Call_Impl, thus do not use it anymore!
    1108         770 :                 pReq->SetSynchronCall( false );
    1109         770 :                 Call_Impl( *pSh, *pSlot, *pReq, pReq->AllowsRecording() ); //! why bRecord?
    1110             :             }
    1111             :         }
    1112             :         else
    1113             :         {
    1114           0 :             if ( pImp->bLocked )
    1115           0 :                 pImp->aReqArr.push_back(new SfxRequest(*pReq));
    1116             :             else
    1117           0 :                 pImp->xPoster->Post(new SfxRequest(*pReq));
    1118             :         }
    1119             :     }
    1120             : 
    1121         770 :     delete pReq;
    1122         770 :     return 0;
    1123             : }
    1124             : 
    1125       11917 : void SfxDispatcher::SetMenu_Impl()
    1126             : {
    1127             : #if HAVE_FEATURE_DESKTOP
    1128       11917 :     if ( pImp->pFrame )
    1129             :     {
    1130       11917 :         SfxViewFrame* pTop = pImp->pFrame->GetTopViewFrame();
    1131       11917 :         if ( pTop && pTop->GetBindings().GetDispatcher() == this )
    1132             :         {
    1133       11917 :             SfxFrame& rFrame = pTop->GetFrame();
    1134       11917 :             if ( rFrame.IsMenuBarOn_Impl() )
    1135             :             {
    1136       11917 :                 com::sun::star::uno::Reference < com::sun::star::beans::XPropertySet > xPropSet( rFrame.GetFrameInterface(), com::sun::star::uno::UNO_QUERY );
    1137       11917 :                 if ( xPropSet.is() )
    1138             :                 {
    1139       11917 :                     com::sun::star::uno::Reference< ::com::sun::star::frame::XLayoutManager > xLayoutManager;
    1140       23834 :                     com::sun::star::uno::Any aValue = xPropSet->getPropertyValue("LayoutManager");
    1141       11917 :                     aValue >>= xLayoutManager;
    1142       11917 :                     if ( xLayoutManager.is() )
    1143             :                     {
    1144       11917 :                         OUString aMenuBarURL( "private:resource/menubar/menubar" );
    1145       11917 :                         if ( !xLayoutManager->isElementVisible( aMenuBarURL ) )
    1146        5456 :                             xLayoutManager->createElement( aMenuBarURL );
    1147       11917 :                     }
    1148       11917 :                 }
    1149             :             }
    1150             :         }
    1151             :     }
    1152             : #endif
    1153       11917 : }
    1154             : 
    1155       13470 : void SfxDispatcher::Update_Impl( bool bForce )
    1156             : {
    1157             :     SFX_STACK(SfxDispatcher::Update_Impl);
    1158             : 
    1159       13470 :     Flush();
    1160             : 
    1161       13470 :     if ( !pImp->pFrame )
    1162           0 :         return;
    1163             : 
    1164       13470 :     SfxGetpApp();  // -Wall is this required???
    1165       13470 :     SfxDispatcher *pDisp = this;
    1166       13470 :     bool bUpdate = bForce;
    1167       40410 :     while ( pDisp && pDisp->pImp->pFrame )
    1168             :     {
    1169       13470 :         SfxWorkWindow *pWork = pDisp->pImp->pFrame->GetFrame().GetWorkWindow_Impl();
    1170       13470 :         SfxDispatcher *pAct = pWork->GetBindings().GetDispatcher_Impl();
    1171       13470 :         if ( pAct == pDisp || pAct == this )
    1172             :         {
    1173       13470 :             if ( !bUpdate )
    1174        7018 :                 bUpdate = !pDisp->pImp->bUpdated;
    1175       13470 :             pDisp->pImp->bUpdated = true;
    1176             :         }
    1177             :         else
    1178             :             break;
    1179             : 
    1180       13470 :         pDisp = pDisp->pImp->pParent;
    1181             :     }
    1182             : 
    1183       13470 :     if ( !bUpdate || pImp->pFrame->GetFrame().IsClosing_Impl() )
    1184        1553 :         return;
    1185             : 
    1186       11917 :     SfxViewFrame* pTop = pImp->pFrame ? pImp->pFrame->GetTopViewFrame() : NULL;
    1187       11917 :     bool bUIActive = pTop && pTop->GetBindings().GetDispatcher() == this;
    1188             : 
    1189       11917 :     if ( !bUIActive && pTop && GetBindings() == &pTop->GetBindings() )
    1190             :         // keep own tools internally for collecting
    1191           0 :         GetBindings()->GetDispatcher()->pImp->bUpdated = false;
    1192             : 
    1193       11917 :     com::sun::star::uno::Reference< com::sun::star::frame::XFrame > xFrame;
    1194       11917 :     SfxBindings* pBindings = GetBindings();
    1195       11917 :     if (pBindings)
    1196             :     {
    1197       11917 :         pBindings->DENTERREGISTRATIONS();
    1198       11917 :         xFrame = pBindings->GetActiveFrame();
    1199             :     }
    1200       23834 :     com::sun::star::uno::Reference< com::sun::star::beans::XPropertySet > xPropSet( xFrame, com::sun::star::uno::UNO_QUERY );
    1201       23834 :     com::sun::star::uno::Reference< ::com::sun::star::frame::XLayoutManager > xLayoutManager;
    1202       11917 :     if ( xPropSet.is() )
    1203             :     {
    1204             :         try
    1205             :         {
    1206       11917 :             com::sun::star::uno::Any aValue = xPropSet->getPropertyValue("LayoutManager");
    1207       11917 :             aValue >>= xLayoutManager;
    1208             :         }
    1209           0 :         catch (const com::sun::star::uno::Exception&)
    1210             :         {
    1211             :         }
    1212             :     }
    1213             : 
    1214       11917 :     if ( xLayoutManager.is() )
    1215       11917 :         xLayoutManager->lock();
    1216             : 
    1217       11917 :     bool bIsIPActive = pImp->pFrame && pImp->pFrame->GetObjectShell()->IsInPlaceActive();
    1218       11917 :     SfxInPlaceClient *pClient = pImp->pFrame ? pImp->pFrame->GetViewShell()->GetUIActiveClient() : NULL;
    1219       11917 :     if ( bUIActive && /* !bIsIPActive && */ ( !pClient || !pClient->IsObjectUIActive() ) )
    1220       11917 :         SetMenu_Impl();
    1221             : 
    1222       11917 :     SfxWorkWindow *pWorkWin = pImp->pFrame->GetFrame().GetWorkWindow_Impl();
    1223       11917 :     SfxWorkWindow *pTaskWin = pImp->pFrame->GetTopFrame().GetWorkWindow_Impl();
    1224       11917 :     pTaskWin->ResetStatusBar_Impl();
    1225             : 
    1226       11917 :     SfxDispatcher *pDispat = this;
    1227       35751 :     while ( pDispat )
    1228             :     {
    1229       11917 :         SfxWorkWindow *pWork = pDispat->pImp->pFrame->GetFrame().GetWorkWindow_Impl();
    1230       11917 :         SfxDispatcher *pAct = pWork->GetBindings().GetDispatcher_Impl();
    1231       11917 :         if ( pAct == pDispat || pAct == this )
    1232             :         {
    1233       11917 :             pWork->ResetObjectBars_Impl();
    1234       11917 :             pWork->ResetChildWindows_Impl();
    1235             :         }
    1236             : 
    1237       11917 :         pDispat = pDispat->pImp->pParent;
    1238             :     }
    1239             : 
    1240       11917 :     bool bIsActive = false;
    1241       11917 :     SfxDispatcher *pActDispat = pWorkWin->GetBindings().GetDispatcher_Impl();
    1242       11917 :     pDispat = this;
    1243       35751 :     while ( pActDispat && !bIsActive )
    1244             :     {
    1245       11917 :         if ( pDispat == pActDispat )
    1246       11917 :             bIsActive = true;
    1247       11917 :         pActDispat = pActDispat->pImp->pParent;
    1248             :     }
    1249             : 
    1250       11917 :     _Update_Impl( bUIActive, !bIsIPActive, bIsIPActive, pTaskWin );
    1251       11917 :     if ( bUIActive || bIsActive )
    1252       11917 :         pWorkWin->UpdateObjectBars_Impl();
    1253             : 
    1254       11917 :     if ( pBindings )
    1255       11917 :         pBindings->DLEAVEREGISTRATIONS();
    1256             : 
    1257       11917 :     if ( xLayoutManager.is() )
    1258       11917 :         xLayoutManager->unlock();
    1259             : 
    1260       23834 :     return;
    1261             : }
    1262             : 
    1263       11917 : void SfxDispatcher::_Update_Impl( bool bUIActive, bool bIsMDIApp, bool bIsIPOwner, SfxWorkWindow *pTaskWin )
    1264             : {
    1265       11917 :     SfxGetpApp();
    1266       11917 :     SfxWorkWindow *pWorkWin = pImp->pFrame->GetFrame().GetWorkWindow_Impl();
    1267       11917 :     bool bIsActive = false;
    1268       11917 :     bool bIsTaskActive = false;
    1269       11917 :     SfxDispatcher *pActDispat = pWorkWin->GetBindings().GetDispatcher_Impl();
    1270       11917 :     SfxDispatcher *pDispat = this;
    1271       35751 :     while ( pActDispat && !bIsActive )
    1272             :     {
    1273       11917 :         if ( pDispat == pActDispat )
    1274       11917 :             bIsActive = true;
    1275       11917 :         pActDispat = pActDispat->pImp->pParent;
    1276             :     }
    1277             : 
    1278       11917 :     if ( pImp->pParent && !pImp->bQuiet /* && bUIActive */ )
    1279           0 :         pImp->pParent->_Update_Impl( bUIActive, bIsMDIApp, bIsIPOwner, pTaskWin );
    1280             : 
    1281      166838 :     for (sal_uInt16 n=0; n<SFX_OBJECTBAR_MAX; n++)
    1282      154921 :         pImp->aObjBars[n].nResId = 0;
    1283       11917 :     pImp->aChildWins.clear();
    1284             : 
    1285             :     // bQuiet : own shells aren't considered for UI and SlotServer
    1286             :     // bNoUI: own Shells aren't considered fors UI
    1287       11917 :     if ( pImp->bQuiet || pImp->bNoUI || (pImp->pFrame && pImp->pFrame->GetObjectShell()->IsPreview()) )
    1288       11917 :         return;
    1289             : 
    1290       11917 :     sal_uInt32 nStatBarId=0;
    1291       11917 :     SfxShell *pStatusBarShell = NULL;
    1292             : 
    1293       11917 :     SfxSlotPool* pSlotPool = &SfxSlotPool::GetSlotPool( GetFrame() );
    1294       11917 :     sal_uInt16 nTotCount = pImp->aStack.size();
    1295       92698 :     for ( sal_uInt16 nShell = nTotCount; nShell > 0; --nShell )
    1296             :     {
    1297       80781 :         SfxShell *pShell = GetShell( nShell-1 );
    1298       80781 :         SfxInterface *pIFace = pShell->GetInterface();
    1299             : 
    1300             :         // don't consider shells if "Hidden" oder "Quiet"
    1301       80781 :         bool bReadOnlyShell = IsReadOnlyShell_Impl( nShell-1 );
    1302             :         sal_uInt16 nNo;
    1303      178257 :         for ( nNo = 0; pIFace && nNo<pIFace->GetObjectBarCount(); ++nNo )
    1304             :         {
    1305       97476 :             sal_uInt16 nPos = pIFace->GetObjectBarPos(nNo);
    1306       97476 :             if ( bReadOnlyShell && !( nPos & SFX_VISIBILITY_READONLYDOC ) )
    1307          52 :                 continue;
    1308             : 
    1309             :             // check whether toolbar needs activation of a special feature
    1310       97424 :             sal_uInt32 nFeature = pIFace->GetObjectBarFeature(nNo);
    1311       97424 :             if ( nFeature && !pShell->HasUIFeature( nFeature ) )
    1312       21741 :                 continue;
    1313             : 
    1314             :             // check for toolboxes that are exclusively for a viewer
    1315       75683 :             if ( pImp->pFrame)
    1316             :             {
    1317       75683 :                 bool bViewerTbx = SFX_VISIBILITY_VIEWER == ( nPos & SFX_VISIBILITY_VIEWER );
    1318       75683 :                 SfxObjectShell* pSh = pImp->pFrame->GetObjectShell();
    1319       75683 :                 SFX_ITEMSET_ARG( pSh->GetMedium()->GetItemSet(), pItem, SfxBoolItem, SID_VIEWONLY, false );
    1320       75683 :                 bool bIsViewer = pItem && pItem->GetValue();
    1321       75683 :                 if ( bIsViewer != bViewerTbx )
    1322       11392 :                     continue;
    1323             :             }
    1324             : 
    1325             :             // always register toolbars, allows to switch them on
    1326       64291 :             bool bVisible = pIFace->IsObjectBarVisible(nNo);
    1327       64291 :             if ( !bVisible )
    1328           0 :                 nPos &= SFX_POSITION_MASK;
    1329             : 
    1330       64291 :             SfxObjectBars_Impl& rBar = pImp->aObjBars[nPos & SFX_POSITION_MASK];
    1331       64291 :             rBar.nMode = nPos;
    1332       64291 :             rBar.nResId = pIFace->GetObjectBarResId(nNo).GetId();
    1333       64291 :             const OUString *pName = pIFace->GetObjectBarName(nNo);
    1334       64291 :             if ( pName )
    1335       64291 :                 rBar.aName = *pName;
    1336             :             else
    1337           0 :                 rBar.aName = "";
    1338       64291 :             rBar.pIFace = pIFace;
    1339             : 
    1340       64291 :             if ( bUIActive || bIsActive )
    1341             :             {
    1342             :                 pWorkWin->SetObjectBar_Impl(
    1343       64291 :                     nPos, rBar.nResId, rBar.pIFace, &rBar.aName );
    1344             :             }
    1345             : 
    1346       64291 :             if ( !bVisible )
    1347           0 :                 rBar.nResId = 0;
    1348             :         }
    1349             : 
    1350      490792 :         for ( nNo=0; pIFace && nNo<pIFace->GetChildWindowCount(); nNo++ )
    1351             :         {
    1352      410011 :             sal_uInt32 nId = pIFace->GetChildWindowId(nNo);
    1353      410011 :             const SfxSlot *pSlot = pSlotPool->GetSlot( (sal_uInt16) nId );
    1354             :             SAL_WARN_IF( !pSlot, "sfx.control", "Childwindow slot missing: " << nId );
    1355      410011 :             if ( bReadOnlyShell )
    1356             :             {
    1357             :                 // only show ChildWindows if their slot is allowed for readonly documents
    1358         294 :                 if ( pSlot && !pSlot->IsMode( SFX_SLOT_READONLYDOC ) )
    1359       49801 :                     continue;
    1360             :             }
    1361             : 
    1362      409831 :             sal_uInt32 nFeature = pIFace->GetChildWindowFeature(nNo);
    1363      409831 :             if ( nFeature && !pShell->HasUIFeature( nFeature ) )
    1364       49441 :                 continue;
    1365             : 
    1366             :             // slot decides whether a ChildWindow is shown when document is OLE server or OLE client
    1367      360390 :             sal_uInt16 nMode = SFX_VISIBILITY_STANDARD;
    1368      360390 :             if( pSlot )
    1369             :             {
    1370      348547 :                 if ( pSlot->IsMode(SFX_SLOT_CONTAINER) )
    1371             :                 {
    1372       35667 :                     if ( pWorkWin->IsVisible_Impl( SFX_VISIBILITY_CLIENT ) )
    1373       35667 :                         nMode |= SFX_VISIBILITY_CLIENT;
    1374             :                 }
    1375             :                 else
    1376             :                 {
    1377      312880 :                     if ( pWorkWin->IsVisible_Impl( SFX_VISIBILITY_SERVER ) )
    1378      312880 :                         nMode |= SFX_VISIBILITY_SERVER;
    1379             :                 }
    1380             :             }
    1381             : 
    1382      360390 :             if ( bUIActive || bIsActive )
    1383      360390 :                 pWorkWin->SetChildWindowVisible_Impl( nId, true, nMode );
    1384      360390 :             if ( bUIActive || bIsActive || !pWorkWin->IsFloating( (sal_uInt16) ( nId & 0xFFFF ) ) )
    1385      360390 :                 pImp->aChildWins.push_back( nId );
    1386             :         }
    1387             : 
    1388       80781 :         if ( bIsMDIApp || bIsIPOwner )
    1389             :         {
    1390       80781 :             sal_uInt32 nId = pIFace->GetStatusBarResId().GetId();
    1391       80781 :             if ( nId )
    1392             :             {
    1393       23834 :                 nStatBarId = nId;
    1394       23834 :                 pStatusBarShell =  pShell;
    1395             :             }
    1396             :         }
    1397             :     }
    1398             : 
    1399      166838 :     for ( sal_uInt16 nPos=0; nPos<SFX_OBJECTBAR_MAX; nPos++ )
    1400             :     {
    1401      154921 :         SfxObjectBars_Impl& rFixed = pImp->aFixedObjBars[nPos];
    1402      154921 :         if ( rFixed.nResId )
    1403             :         {
    1404           0 :             SfxObjectBars_Impl& rBar = pImp->aObjBars[nPos];
    1405           0 :             rBar = rFixed;
    1406             :             pWorkWin->SetObjectBar_Impl( rFixed.nMode,
    1407           0 :                 rFixed.nResId, rFixed.pIFace, &rFixed.aName );
    1408             :         }
    1409             :     }
    1410             : 
    1411       11917 :     if ( pTaskWin && ( bIsMDIApp || bIsIPOwner ) )
    1412             :     {
    1413       11917 :         SfxDispatcher *pActDispatcher = pTaskWin->GetBindings().GetDispatcher_Impl();
    1414       11917 :         SfxDispatcher *pDispatcher = this;
    1415       35751 :         while ( pActDispatcher && !bIsTaskActive )
    1416             :         {
    1417       11917 :             if ( pDispatcher == pActDispatcher )
    1418       11917 :                 bIsTaskActive = true;
    1419       11917 :             pActDispatcher = pActDispatcher->pImp->pParent;
    1420             :         }
    1421             : 
    1422       11917 :         if ( bIsTaskActive && nStatBarId && pImp->pFrame )
    1423             :         {
    1424             :             // internal frames also may control statusbar
    1425       11917 :             SfxBindings& rBindings = pImp->pFrame->GetBindings();
    1426       11917 :             pImp->pFrame->GetFrame().GetWorkWindow_Impl()->SetStatusBar_Impl( nStatBarId, pStatusBarShell, rBindings );
    1427             :         }
    1428             :     }
    1429             : }
    1430             : 
    1431             : /** Helper method to execute the outstanding push and pop commands.
    1432             : */
    1433       28255 : void SfxDispatcher::FlushImpl()
    1434             : {
    1435             :     SFX_STACK(SfxDispatcher::FlushImpl);
    1436             : 
    1437             :     OSL_TRACE("Flushing dispatcher!");
    1438             : 
    1439       28255 :     pImp->aTimer.Stop();
    1440             : 
    1441       28255 :     if ( pImp->pParent )
    1442           0 :         pImp->pParent->Flush();
    1443             : 
    1444       28255 :     pImp->bFlushing = !pImp->bFlushing;
    1445       28255 :     if ( !pImp->bFlushing )
    1446             :     {
    1447           0 :         pImp->bFlushing = true;
    1448       28255 :         return;
    1449             :     }
    1450             : 
    1451       28255 :     SfxApplication *pSfxApp = SfxGetpApp();
    1452             : 
    1453             :     // Re-build the true stack in the first round
    1454       28255 :     std::deque<SfxToDo_Impl> aToDoCopy;
    1455       28255 :     bool bModify = false;
    1456       89506 :     for(std::deque<SfxToDo_Impl>::reverse_iterator i = pImp->aToDoStack.rbegin(); i != pImp->aToDoStack.rend(); ++i)
    1457             :     {
    1458       61251 :         bModify = true;
    1459             : 
    1460       61251 :         if(i->bPush)
    1461             :         {
    1462             :             // Actually push
    1463             :             DBG_ASSERT( std::find(pImp->aStack.begin(), pImp->aStack.end(), i->pCluster) == pImp->aStack.end(),
    1464             :                        "pushed SfxShell already on stack" );
    1465       44661 :             pImp->aStack.push_back(i->pCluster);
    1466       44661 :             i->pCluster->SetDisableFlags(pImp->nDisableFlags);
    1467             : 
    1468             :             // Mark the moved shell
    1469       44661 :             aToDoCopy.push_front(*i);
    1470             :         }
    1471             :         else
    1472             :         {
    1473             :             // Actually pop
    1474       16590 :             SfxShell* pPopped = 0;
    1475       16590 :             bool bFound = false;
    1476       26978 :             do
    1477             :             {
    1478             :                 DBG_ASSERT( !pImp->aStack.empty(), "popping from empty stack" );
    1479       26978 :                 pPopped = pImp->aStack.back();
    1480       26978 :                 pImp->aStack.pop_back();
    1481       26978 :                 pPopped->SetDisableFlags( 0 );
    1482       26978 :                 bFound = (pPopped == i->pCluster);
    1483             : 
    1484             :                 // Mark the moved Shell
    1485       26978 :                 aToDoCopy.push_front(SfxToDo_Impl(false, i->bDelete, false, *pPopped));
    1486             :             }
    1487       26978 :             while(i->bUntil && !bFound);
    1488             :             DBG_ASSERT( bFound, "wrong SfxShell popped" );
    1489             :         }
    1490             :     }
    1491       28255 :     pImp->aToDoStack.clear();
    1492             : 
    1493             :     // Invalidate bindings, if possible
    1494       28255 :     if ( !pSfxApp->IsDowning() )
    1495             :     {
    1496       28255 :         if ( bModify )
    1497             :         {
    1498       28255 :             pImp->pCachedServ1 = 0;
    1499       28255 :             pImp->pCachedServ2 = 0;
    1500             :         }
    1501             : 
    1502       28255 :         InvalidateBindings_Impl( bModify );
    1503             :     }
    1504             : 
    1505       28255 :     pImp->bFlushing = false;
    1506       28255 :     pImp->bUpdated = false; // not only when bModify, if Doc/Template-Config
    1507       28255 :     pImp->bFlushed = true;
    1508             :     OSL_TRACE("Successfully flushed dispatcher!");
    1509             : 
    1510             :     //fdo#70703 FlushImpl may call back into itself so use aToDoCopyStack to talk
    1511             :     //to outer levels of ourself. If DoActivate_Impl/DoDeactivate_Impl deletes
    1512             :     //an entry, then they will walk back up aToDoCopyStack and set outer
    1513             :     //levels's entries to bDeleted
    1514       28255 :     pImp->aToDoCopyStack.push_back(aToDoCopy);
    1515       28255 :     std::deque<SfxToDo_Impl>& rToDoCopy = pImp->aToDoCopyStack.back();
    1516             :     // Activate the Shells and possible delete them in the 2nd round
    1517       99894 :     for(std::deque<SfxToDo_Impl>::reverse_iterator i = rToDoCopy.rbegin(); i != rToDoCopy.rend(); ++i)
    1518             :     {
    1519       71639 :         if (i->bDeleted)
    1520           0 :             continue;
    1521       71639 :         if (!pImp->bActive)
    1522       56573 :             continue;
    1523       15066 :         if (i->bPush)
    1524       14698 :             i->pCluster->DoActivate_Impl(pImp->pFrame, true);
    1525             :         else
    1526         368 :             i->pCluster->DoDeactivate_Impl(pImp->pFrame, true);
    1527             :     }
    1528             : 
    1529       28255 :     aToDoCopy = pImp->aToDoCopyStack.back();
    1530       28255 :     pImp->aToDoCopyStack.pop_back();
    1531             : 
    1532       99894 :     for(std::deque<SfxToDo_Impl>::reverse_iterator i = aToDoCopy.rbegin(); i != aToDoCopy.rend(); ++i)
    1533             :     {
    1534       71639 :         if (i->bDelete && !i->bDeleted)
    1535             :         {
    1536       14648 :             if (!pImp->aToDoCopyStack.empty())
    1537             :             {
    1538             :                 //fdo#70703 if there is an outer FlushImpl then inform it that
    1539             :                 //we have deleted this cluster
    1540           0 :                 for (std::deque< std::deque<SfxToDo_Impl> >::iterator aI = pImp->aToDoCopyStack.begin();
    1541           0 :                     aI != pImp->aToDoCopyStack.end(); ++aI)
    1542             :                 {
    1543           0 :                     std::deque<SfxToDo_Impl> &v = *aI;
    1544           0 :                     for(std::deque<SfxToDo_Impl>::iterator aJ = v.begin(); aJ != v.end(); ++aJ)
    1545             :                     {
    1546           0 :                         if (aJ->pCluster == i->pCluster)
    1547           0 :                             aJ->bDeleted = true;
    1548             :                     }
    1549             :                 }
    1550             :             }
    1551       14648 :             delete i->pCluster;
    1552             :         }
    1553             :     }
    1554       28255 :     bool bAwakeBindings = !aToDoCopy.empty();
    1555       28255 :     if( bAwakeBindings )
    1556       28255 :         aToDoCopy.clear();
    1557             : 
    1558             :     // If more changes have occurred on the stach when
    1559             :     // Activate/Deactivate/Delete:
    1560       28255 :     if (!pImp->bFlushed)
    1561             :         // If Push/Pop hs been called by someone, theb also EnterReg was called!
    1562           0 :         FlushImpl();
    1563             : 
    1564       28255 :     if( bAwakeBindings && GetBindings() )
    1565       27784 :         GetBindings()->DLEAVEREGISTRATIONS();
    1566             : 
    1567      395570 :     for (sal_uInt16 n=0; n<SFX_OBJECTBAR_MAX; n++)
    1568      367315 :         pImp->aFixedObjBars[n].nResId = 0;
    1569             : 
    1570       28255 :     SAL_INFO("sfx.control", "SfxDispatcher(" << this << ")::Flush() done");
    1571             : }
    1572             : 
    1573             : /** With this method a filter set, the target slots can be enabled or disabled.
    1574             :     The passed array must be retained until the destructor or the next
    1575             :     <SetSlotFilter()>, it is not deleted from the dispatcher, so it can thus be
    1576             :     static.
    1577             : 
    1578             :     In read-only documents the quasi ReadOnlyDoc Flag of slots can be
    1579             :     overturned by the use of 'bEnable == 2', so this will be displayed again.
    1580             :     On the other slots it has no effect.
    1581             : 
    1582             :     // HACK(hier muss mal ein enum rein) ???
    1583             :     @param nEnable  1==true: only enable specified slots, disable all other
    1584             :                     0==false: disable specified slots, first enable all other
    1585             :     @param nCount Number of SIDs in the following Array
    1586             :     @param pSIDs sorted Array of 'nCount' SIDs
    1587             : 
    1588             :     [Example]
    1589             : 
    1590             :     Targeted disabling of Slots 1, 2 and 3:
    1591             : 
    1592             :         static sal_uInt16 const pSIDs[] = { 1, 2, 3 };
    1593             :         pDisp->SetSlotFilter( sal_False, sizeof(pSIDs)/sizeof(sal_uInt16), pSIDs );
    1594             : 
    1595             :     only permit Slots 5, 6 and 7:
    1596             : 
    1597             :         static sal_uInt16 const pSIDs[] = { 5, 6, 7 };
    1598             :         pDisp->SetSlotFilter( sal_True, sizeof(pSIDs)/sizeof(sal_uInt16), pSIDs );
    1599             : 
    1600             :     Turn-off Filter:
    1601             : 
    1602             :         pDisp->SetSlotFilter();
    1603             : */
    1604         212 : void SfxDispatcher::SetSlotFilter(SfxSlotFilterState nEnable,
    1605             :         sal_uInt16 nCount, const sal_uInt16* pSIDs)
    1606             : {
    1607             : #ifdef DBG_UTIL
    1608             :     // Check Array
    1609             :     for ( sal_uInt16 n = 1; n < nCount; ++n )
    1610             :         DBG_ASSERT( pSIDs[n] > pSIDs[n-1], "SetSlotFilter: SIDs not sorted" );
    1611             : #endif
    1612             : 
    1613         212 :     if ( pImp->pFilterSIDs )
    1614           0 :         pImp->pFilterSIDs = 0;
    1615             : 
    1616         212 :     pImp->nFilterEnabling = nEnable;
    1617         212 :     pImp->nFilterCount = nCount;
    1618         212 :     pImp->pFilterSIDs = pSIDs;
    1619             : 
    1620         212 :     GetBindings()->InvalidateAll(true);
    1621         212 : }
    1622             : 
    1623           0 : extern "C" int SAL_CALL SfxCompareSIDs_Impl(const void* pSmaller, const void* pBigger)
    1624             : {
    1625           0 :     return ( (long) *((sal_uInt16*)pSmaller) ) - ( (long) *((sal_uInt16*)pBigger) );
    1626             : }
    1627             : 
    1628             : /** Searches for 'nSID' in the Filter set by <SetSlotFilter()> and
    1629             :     returns sal_True, if the SIDis allowed, or sal_False, if it is
    1630             :     disabled by the Filter.
    1631             : 
    1632             :     @return             0       =>      disabled
    1633             :                         1       =>      enabled
    1634             :                         2       =>      enabled even if ReadOnlyDoc
    1635             : */
    1636      259662 : SfxSlotFilterState SfxDispatcher::IsSlotEnabledByFilter_Impl( sal_uInt16 nSID ) const
    1637             : {
    1638             :     // no filter?
    1639      259662 :     if ( 0 == pImp->nFilterCount )
    1640             :         // => all SIDs allowed
    1641      259662 :         return SFX_SLOT_FILTER_ENABLED;
    1642             : 
    1643             :     // search
    1644           0 :     bool bFound = 0 != bsearch( &nSID, pImp->pFilterSIDs, pImp->nFilterCount,
    1645           0 :                                 sizeof(sal_uInt16), SfxCompareSIDs_Impl );
    1646             : 
    1647             :     // even if ReadOnlyDoc
    1648           0 :     if ( SFX_SLOT_FILTER_ENABLED_READONLY == pImp->nFilterEnabling )
    1649           0 :         return bFound ? SFX_SLOT_FILTER_ENABLED_READONLY : SFX_SLOT_FILTER_ENABLED;
    1650             :     // Otherwise after Negative/Positive Filter
    1651           0 :     else if ( SFX_SLOT_FILTER_ENABLED == pImp->nFilterEnabling )
    1652           0 :         return bFound ? SFX_SLOT_FILTER_ENABLED : SFX_SLOT_FILTER_DISABLED;
    1653             :     else
    1654           0 :         return bFound ? SFX_SLOT_FILTER_DISABLED : SFX_SLOT_FILTER_ENABLED;
    1655             : }
    1656             : 
    1657           0 : bool SfxDispatcher::_TryIntercept_Impl
    1658             : (
    1659             :     sal_uInt16      nSlot,    // Slot-Id to search for
    1660             :     SfxSlotServer&  rServer,  // <SfxSlotServer>-Instance to fill
    1661             :     bool            bSelf
    1662             : )
    1663             : {
    1664             :     // Maybe the parent is also belongs to a component
    1665           0 :     SfxDispatcher *pParent = pImp->pParent;
    1666           0 :     sal_uInt16 nLevels = pImp->aStack.size();
    1667           0 :     while ( pParent && pParent->pImp->pFrame )
    1668             :     {
    1669           0 :         if ( pParent->pImp->pFrame->GetFrame().HasComponent() )
    1670             :         {
    1671             :             // Components may be intercepted
    1672           0 :             if ( pParent->_TryIntercept_Impl( nSlot, rServer, true ) )
    1673             :             {
    1674             :                 // The own shells are added to the Shell Level
    1675           0 :                 rServer.SetShellLevel( rServer.GetShellLevel() + nLevels );
    1676           0 :                 return true;
    1677             :             }
    1678             :             else
    1679             :                 // No further Interception
    1680           0 :                 break;
    1681             :         }
    1682             :         else
    1683           0 :             nLevels = nLevels + pParent->pImp->aStack.size();
    1684             : 
    1685           0 :         pParent = pParent->pImp->pParent;
    1686             :     }
    1687             : 
    1688           0 :     if ( bSelf )
    1689             :     {
    1690             :         // Query the ComponentViewShell
    1691           0 :         Flush();
    1692           0 :         SfxShell *pObjShell = GetShell(0);
    1693           0 :         SfxInterface *pIFace = pObjShell->GetInterface();
    1694           0 :         const SfxSlot *pSlot = pIFace->GetSlot(nSlot);
    1695             : 
    1696           0 :         if ( pSlot )
    1697             :         {
    1698           0 :             rServer.SetSlot(pSlot);
    1699           0 :             rServer.SetShellLevel(0);
    1700           0 :             return true;
    1701             :         }
    1702             :     }
    1703             : 
    1704           0 :     return false;
    1705             : }
    1706             : 
    1707             : /** This helper method searches for the <Slot-Server> which currently serves
    1708             :     the nSlot. As the result, rServe is filled accordingly.
    1709             : 
    1710             :     If known the SfxInterface which is currently served by nSlot can be
    1711             :     passed along.
    1712             : 
    1713             :     The SfxDispatcher is flushed while searching for nSlot.
    1714             : 
    1715             :     @param nSlot Slot-Id to search for
    1716             :     @param rServer <SfxSlotServer>-Instance to fill
    1717             :     @param bModal Dispite ModalMode
    1718             : 
    1719             :     @return         true
    1720             :                     The Slot was found, rServer is valid.
    1721             : 
    1722             :                     false
    1723             :                     The Slot is currently not served, rServer is invalid.
    1724             : */
    1725      259781 : bool SfxDispatcher::_FindServer(sal_uInt16 nSlot, SfxSlotServer& rServer, bool bModal)
    1726             : {
    1727             :     SFX_STACK(SfxDispatcher::_FindServer);
    1728             : 
    1729             :     // Dispatcher locked? (nevertheless let SID_HELP_PI through)
    1730      259781 :     if ( IsLocked(nSlot) )
    1731             :     {
    1732           0 :         pImp->bInvalidateOnUnlock = true;
    1733           0 :         return false;
    1734             :     }
    1735             : 
    1736             :     // Count the number of Shells in the linked dispatchers.
    1737      259781 :     Flush();
    1738      259781 :     sal_uInt16 nTotCount = pImp->aStack.size();
    1739      259781 :     if ( pImp->pParent )
    1740             :     {
    1741           0 :         SfxDispatcher *pParent = pImp->pParent;
    1742           0 :         while ( pParent )
    1743             :         {
    1744           0 :             nTotCount = nTotCount + pParent->pImp->aStack.size();
    1745           0 :             pParent = pParent->pImp->pParent;
    1746             :         }
    1747             :     }
    1748             : 
    1749             :     // Verb-Slot?
    1750      259781 :     if (nSlot >= SID_VERB_START && nSlot <= SID_VERB_END)
    1751             :     {
    1752           0 :         for ( sal_uInt16 nShell = 0;; ++nShell )
    1753             :         {
    1754           0 :             SfxShell *pSh = GetShell(nShell);
    1755           0 :             if ( pSh == NULL )
    1756           0 :                 return false;
    1757           0 :             if ( pSh->ISA(SfxViewShell) )
    1758             :             {
    1759           0 :                 const SfxSlot* pSlot = pSh->GetVerbSlot_Impl(nSlot);
    1760           0 :                 if ( pSlot )
    1761             :                 {
    1762           0 :                     rServer.SetShellLevel(nShell);
    1763           0 :                     rServer.SetSlot( pSlot );
    1764           0 :                     return true;
    1765             :                 }
    1766             :             }
    1767           0 :         }
    1768             :     }
    1769             : 
    1770             :     // SID check against set filter
    1771      259781 :     SfxSlotFilterState nSlotEnableMode = SFX_SLOT_FILTER_DISABLED;
    1772      259781 :     if ( pImp->pFrame )
    1773             :     {
    1774      259662 :         nSlotEnableMode = IsSlotEnabledByFilter_Impl( nSlot );
    1775      259662 :         if ( SFX_SLOT_FILTER_DISABLED == nSlotEnableMode )
    1776           0 :             return false;
    1777             :     }
    1778             : 
    1779             :     // In Quiet-Mode only Parent-Dispatcher
    1780      259781 :     if ( pImp->bQuiet )
    1781             :     {
    1782           0 :         if ( pImp->pParent )
    1783             :         {
    1784           0 :             bool bRet = pImp->pParent->_FindServer( nSlot, rServer, bModal );
    1785             :             rServer.SetShellLevel
    1786           0 :                 ( rServer.GetShellLevel() + pImp->aStack.size() );
    1787           0 :             return bRet;
    1788             :         }
    1789             :         else
    1790           0 :             return false;
    1791             :     }
    1792             : 
    1793      259781 :     bool bReadOnly = ( SFX_SLOT_FILTER_ENABLED_READONLY != nSlotEnableMode && pImp->bReadOnly );
    1794             : 
    1795             :     // search through all the shells of the chained dispatchers
    1796             :     // from top to bottom
    1797      259781 :     sal_uInt16 nFirstShell = pImp->bModal && !bModal ? pImp->aStack.size() : 0;
    1798      635956 :     for ( sal_uInt16 i = nFirstShell; i < nTotCount; ++i )
    1799             :     {
    1800      627086 :         SfxShell *pObjShell = GetShell(i);
    1801      627086 :         SfxInterface *pIFace = pObjShell->GetInterface();
    1802      627086 :         const SfxSlot *pSlot = pIFace->GetSlot(nSlot);
    1803             : 
    1804      627086 :         if ( pSlot && pSlot->nDisableFlags && ( pSlot->nDisableFlags & pObjShell->GetDisableFlags() ) != 0 )
    1805           0 :             return false;
    1806             : 
    1807      627086 :         if ( pSlot && !( pSlot->nFlags & SFX_SLOT_READONLYDOC ) && bReadOnly )
    1808          98 :             return false;
    1809             : 
    1810      626988 :         if ( pSlot )
    1811             :         {
    1812             :             // Slot belongs to Container?
    1813      250921 :             bool bIsContainerSlot = pSlot->IsMode(SFX_SLOT_CONTAINER);
    1814      250921 :             bool bIsInPlace = pImp->pFrame && pImp->pFrame->GetObjectShell()->IsInPlaceActive();
    1815             : 
    1816             :             // Shell belongs to Server?
    1817             :             // AppDispatcher or IPFrame-Dispatcher
    1818      250921 :             bool bIsServerShell = !pImp->pFrame || bIsInPlace;
    1819             : 
    1820             :             // Of course ShellServer-Slots are also executable even when it is
    1821             :             // excecuted on a container dispatcher without a IPClient.
    1822      250921 :             if ( !bIsServerShell )
    1823             :             {
    1824      250802 :                 SfxViewShell *pViewSh = pImp->pFrame->GetViewShell();
    1825      250802 :                 bIsServerShell = !pViewSh || !pViewSh->GetUIActiveClient();
    1826             :             }
    1827             : 
    1828             :             // Shell belongs to Container?
    1829             :             // AppDispatcher or no IPFrameDispatcher
    1830      250921 :             bool bIsContainerShell = !pImp->pFrame || !bIsInPlace;
    1831             :             // Shell and Slot match
    1832      250921 :             if ( !( ( bIsContainerSlot && bIsContainerShell ) ||
    1833      230346 :                     ( !bIsContainerSlot && bIsServerShell ) ) )
    1834         108 :                 pSlot = 0;
    1835             :         }
    1836             : 
    1837      626988 :         if ( pSlot )
    1838             :         {
    1839      250813 :             rServer.SetSlot(pSlot);
    1840      250813 :             rServer.SetShellLevel(i);
    1841      250813 :             return true;
    1842             :         }
    1843             :     }
    1844             : 
    1845        8870 :     return false;
    1846             : }
    1847             : 
    1848             : /** Helper method to obtain the status of the <Slot-Server>s rSvr.
    1849             :     The required slots IDs (partly converted to Which-IDs of the pool)
    1850             :     must be present in rstate.
    1851             : 
    1852             :     The SfxDispatcher is flushed before the query.
    1853             : 
    1854             :     @param rSvr Slot-Server to query
    1855             :     @param rState SfxItemSet to be filled
    1856             :     @param pRealSlot The actual Slot if possible
    1857             : */
    1858       11428 : bool SfxDispatcher::_FillState(const SfxSlotServer& rSvr, SfxItemSet& rState,
    1859             :         const SfxSlot* pRealSlot)
    1860             : {
    1861             :     SFX_STACK(SfxDispatcher::_FillState);
    1862             : 
    1863       11428 :     const SfxSlot *pSlot = rSvr.GetSlot();
    1864       11428 :     if ( pSlot && IsLocked( pSlot->GetSlotId() ) )
    1865             :     {
    1866           0 :         pImp->bInvalidateOnUnlock = true;
    1867           0 :         return false;
    1868             :     }
    1869             : 
    1870       11428 :     if ( pSlot )
    1871             :     {
    1872             :         DBG_ASSERT(pImp->bFlushed,
    1873             :                 "Dispatcher not flushed after retrieving slot servers!");
    1874       11428 :         if (!pImp->bFlushed)
    1875           0 :             return false;
    1876             : 
    1877             :         // Determine the object and call the Message of this object
    1878       11428 :         SfxShell *pSh = GetShell(rSvr.GetShellLevel());
    1879             :         DBG_ASSERT(pSh, "ObjectShell not found");
    1880             : 
    1881             :         SfxStateFunc pFunc;
    1882             : 
    1883       11428 :         if (pRealSlot)
    1884       11428 :             pFunc = pRealSlot->GetStateFnc();
    1885             :         else
    1886           0 :             pFunc = pSlot->GetStateFnc();
    1887             : 
    1888       11428 :         pSh->CallState( pFunc, rState );
    1889             : #ifdef DBG_UTIL
    1890             :         // To examine the conformity of IDL (SlotMap) and current Items
    1891             :         if ( rState.Count() )
    1892             :         {
    1893             :             SfxInterface *pIF = pSh->GetInterface();
    1894             :             SfxItemIter aIter( rState );
    1895             :             for ( const SfxPoolItem *pItem = aIter.FirstItem();
    1896             :                   pItem;
    1897             :                   pItem = aIter.NextItem() )
    1898             :             {
    1899             :                 if ( !IsInvalidItem(pItem) && !pItem->ISA(SfxVoidItem) )
    1900             :                 {
    1901             :                     sal_uInt16 nSlotId = rState.GetPool()->GetSlotId(pItem->Which());
    1902             :                     SAL_INFO_IF(
    1903             :                         !pItem->IsA(pIF->GetSlot(nSlotId)->GetType()->Type()),
    1904             :                         "sfx.control",
    1905             :                         "item-type unequal to IDL (=> no BASIC) with SID: "
    1906             :                             << nSlotId << " in " << pIF->GetClassName());
    1907             :                 }
    1908             :             }
    1909             :         }
    1910             : #endif
    1911             : 
    1912       11428 :         return true;
    1913             :     }
    1914             : 
    1915           0 :     return false;
    1916             : }
    1917             : 
    1918           0 : SfxPopupMenuManager* SfxDispatcher::Popup( sal_uInt16 nConfigId, vcl::Window *pWin, const Point *pPos )
    1919             : {
    1920           0 :     SfxDispatcher &rDisp = *SfxGetpApp()->GetDispatcher_Impl();
    1921           0 :     sal_uInt16 nShLevel = 0;
    1922             :     SfxShell *pSh;
    1923             : 
    1924           0 :     if ( rDisp.pImp->bQuiet )
    1925             :     {
    1926           0 :         nConfigId = 0;
    1927           0 :         nShLevel = rDisp.pImp->aStack.size();
    1928             :     }
    1929             : 
    1930           0 :     vcl::Window *pWindow = pWin ? pWin : rDisp.pImp->pFrame->GetFrame().GetWorkWindow_Impl()->GetWindow();
    1931           0 :     for ( pSh = rDisp.GetShell(nShLevel); pSh; ++nShLevel, pSh = rDisp.GetShell(nShLevel) )
    1932             :     {
    1933           0 :         const ResId& rResId = pSh->GetInterface()->GetPopupMenuResId();
    1934           0 :         if ( ( nConfigId == 0 && rResId.GetId() ) || ( nConfigId != 0 && rResId.GetId() == nConfigId ) )
    1935             :         {
    1936           0 :                 return SfxPopupMenuManager::Popup( rResId, rDisp.GetFrame(), pPos ? *pPos : pWindow->GetPointerPosPixel(), pWindow );
    1937             :         }
    1938             :     }
    1939           0 :     return 0;
    1940             : }
    1941             : 
    1942           0 : void SfxDispatcher::ExecutePopup( sal_uInt16 nConfigId, vcl::Window *pWin, const Point *pPos )
    1943             : {
    1944           0 :     SfxDispatcher &rDisp = *SfxGetpApp()->GetDispatcher_Impl();
    1945           0 :     sal_uInt16 nShLevel = 0;
    1946             :     SfxShell *pSh;
    1947             : 
    1948           0 :     if ( rDisp.pImp->bQuiet )
    1949             :     {
    1950           0 :         nConfigId = 0;
    1951           0 :         nShLevel = rDisp.pImp->aStack.size();
    1952             :     }
    1953             : 
    1954           0 :     vcl::Window *pWindow = pWin ? pWin : rDisp.pImp->pFrame->GetFrame().GetWorkWindow_Impl()->GetWindow();
    1955           0 :     for ( pSh = rDisp.GetShell(nShLevel); pSh; ++nShLevel, pSh = rDisp.GetShell(nShLevel) )
    1956             :     {
    1957           0 :         const ResId& rResId = pSh->GetInterface()->GetPopupMenuResId();
    1958           0 :         if ( ( nConfigId == 0 && rResId.GetId() ) || ( nConfigId != 0 && rResId.GetId() == nConfigId ) )
    1959             :         {
    1960           0 :             SfxPopupMenuManager::ExecutePopup( rResId, rDisp.GetFrame(), pPos ? *pPos : pWindow->GetPointerPosPixel(), pWindow );
    1961           0 :             return;
    1962             :         }
    1963             :     }
    1964             : }
    1965             : 
    1966           0 : void SfxDispatcher::ExecutePopup( const ResId &rId, vcl::Window *pWin, const Point *pPos )
    1967             : {
    1968           0 :     vcl::Window *pWindow = pWin ? pWin : pImp->pFrame->GetFrame().GetWorkWindow_Impl()->GetWindow();
    1969           0 :     SfxPopupMenuManager::ExecutePopup( rId, GetFrame(), pPos ? *pPos : pWindow->GetPointerPosPixel(), pWindow );
    1970           0 : }
    1971             : 
    1972             : /** With this method the SfxDispatcher can be locked and released. A locked
    1973             :     SfxDispatcher does not perform <SfxRequest>s and does no longer provide
    1974             :     status information. It behaves as if all the slots were disabled.
    1975             : */
    1976       20770 : void SfxDispatcher::Lock( bool bLock )
    1977             : {
    1978       20770 :     SfxBindings* pBindings = GetBindings();
    1979       20770 :     if ( !bLock && pImp->bLocked && pImp->bInvalidateOnUnlock )
    1980             :     {
    1981           0 :         if ( pBindings )
    1982           0 :             pBindings->InvalidateAll(true);
    1983           0 :         pImp->bInvalidateOnUnlock = false;
    1984             :     }
    1985       20770 :     else if ( pBindings )
    1986       20770 :         pBindings->InvalidateAll(false);
    1987       20770 :     pImp->bLocked = bLock;
    1988       20770 :     if ( !bLock )
    1989             :     {
    1990       10392 :         for(size_t i = 0; i < pImp->aReqArr.size(); ++i)
    1991           0 :             pImp->xPoster->Post(pImp->aReqArr[i]);
    1992       10392 :         pImp->aReqArr.clear();
    1993             :     }
    1994       20770 : }
    1995             : 
    1996          48 : sal_uInt32 SfxDispatcher::GetObjectBarId( sal_uInt16 nPos ) const
    1997             : {
    1998          48 :     return pImp->aObjBars[nPos].nResId;
    1999             : }
    2000             : 
    2001        5454 : void SfxDispatcher::HideUI( bool bHide )
    2002             : {
    2003        5454 :     bool bWasHidden = pImp->bNoUI;
    2004        5454 :     pImp->bNoUI = bHide;
    2005        5454 :     if ( pImp->pFrame )
    2006             :     {
    2007        5454 :         SfxViewFrame* pTop = pImp->pFrame->GetTopViewFrame();
    2008        5454 :         if ( pTop && pTop->GetBindings().GetDispatcher() == this )
    2009             :         {
    2010        5454 :             SfxFrame& rFrame = pTop->GetFrame();
    2011        5454 :             if ( rFrame.IsMenuBarOn_Impl() )
    2012             :             {
    2013        5454 :                 com::sun::star::uno::Reference < com::sun::star::beans::XPropertySet > xPropSet( rFrame.GetFrameInterface(), com::sun::star::uno::UNO_QUERY );
    2014        5454 :                 if ( xPropSet.is() )
    2015             :                 {
    2016        5454 :                     com::sun::star::uno::Reference< ::com::sun::star::frame::XLayoutManager > xLayoutManager;
    2017       10908 :                     com::sun::star::uno::Any aValue = xPropSet->getPropertyValue("LayoutManager");
    2018        5454 :                     aValue >>= xLayoutManager;
    2019        5454 :                     if ( xLayoutManager.is() )
    2020       10908 :                         xLayoutManager->setVisible( !bHide );
    2021        5454 :                 }
    2022             :             }
    2023             :         }
    2024             :     }
    2025             : 
    2026        5454 :     if ( bHide != bWasHidden )
    2027           0 :         Update_Impl( true );
    2028        5454 : }
    2029             : 
    2030        5508 : void SfxDispatcher::SetReadOnly_Impl( bool bOn )
    2031             : {
    2032        5508 :     pImp->bReadOnly = bOn;
    2033        5508 : }
    2034             : 
    2035          20 : bool SfxDispatcher::GetReadOnly_Impl() const
    2036             : {
    2037          20 :     return pImp->bReadOnly;
    2038             : }
    2039             : 
    2040             : /** With 'bOn' the Dispatcher is quasi dead and transfers everything to the
    2041             :     Parent-Dispatcher.
    2042             : */
    2043           0 : void SfxDispatcher::SetQuietMode_Impl( bool bOn )
    2044             : {
    2045           0 :     pImp->bQuiet = bOn;
    2046           0 :     SfxBindings* pBindings = GetBindings();
    2047           0 :     if ( pBindings )
    2048           0 :         pBindings->InvalidateAll(true);
    2049           0 : }
    2050             : 
    2051        8669 : SfxItemState SfxDispatcher::QueryState( sal_uInt16 nSlot, const SfxPoolItem* &rpState )
    2052             : {
    2053        8669 :     SfxShell *pShell = 0;
    2054        8669 :     const SfxSlot *pSlot = 0;
    2055        8669 :     if ( GetShellAndSlot_Impl( nSlot, &pShell, &pSlot, false, false ) )
    2056             :     {
    2057        8633 :         rpState = pShell->GetSlotState(nSlot);
    2058        8633 :         if ( !rpState )
    2059           1 :             return SfxItemState::DISABLED;
    2060             :         else
    2061        8632 :             return SfxItemState::DEFAULT;
    2062             :     }
    2063             : 
    2064          36 :     return SfxItemState::DISABLED;
    2065             : }
    2066             : 
    2067      140869 : SfxItemState SfxDispatcher::QueryState( sal_uInt16 nSID, ::com::sun::star::uno::Any& rAny )
    2068             : {
    2069      140869 :     SfxShell *pShell = 0;
    2070      140869 :     const SfxSlot *pSlot = 0;
    2071      140869 :     if ( GetShellAndSlot_Impl( nSID, &pShell, &pSlot, false, false ) )
    2072             :     {
    2073      137131 :         const SfxPoolItem* pItem( 0 );
    2074             : 
    2075      137131 :         pItem = pShell->GetSlotState( nSID );
    2076      137131 :         if ( !pItem )
    2077        9095 :             return SfxItemState::DISABLED;
    2078             :         else
    2079             :         {
    2080      128036 :             ::com::sun::star::uno::Any aState;
    2081      128036 :             if ( !pItem->ISA(SfxVoidItem) )
    2082             :             {
    2083       88548 :                 sal_uInt16 nSubId( 0 );
    2084       88548 :                 SfxItemPool& rPool = pShell->GetPool();
    2085       88548 :                 sal_uInt16 nWhich = rPool.GetWhich( nSID );
    2086       88548 :                 if ( rPool.GetMetric( nWhich ) == SFX_MAPUNIT_TWIP )
    2087       73971 :                     nSubId |= CONVERT_TWIPS;
    2088       88548 :                 pItem->QueryValue( aState, (sal_uInt8)nSubId );
    2089             :             }
    2090      128036 :             rAny = aState;
    2091             : 
    2092      128036 :             return SfxItemState::DEFAULT;
    2093             :         }
    2094             :     }
    2095             : 
    2096        3738 :     return SfxItemState::DISABLED;
    2097             : }
    2098             : 
    2099       80781 : bool SfxDispatcher::IsReadOnlyShell_Impl( sal_uInt16 nShell ) const
    2100             : {
    2101       80781 :     sal_uInt16 nShellCount = pImp->aStack.size();
    2102       80781 :     if ( nShell < nShellCount )
    2103             :     {
    2104       80781 :         SfxShell* pShell = *( pImp->aStack.rbegin() + nShell );
    2105       80781 :         if( pShell->ISA( SfxModule ) || pShell->ISA( SfxApplication ) || pShell->ISA( SfxViewFrame ) )
    2106       35751 :             return false;
    2107             :         else
    2108       45030 :             return pImp->bReadOnly;
    2109             :     }
    2110           0 :     else if ( pImp->pParent )
    2111           0 :         return pImp->pParent->IsReadOnlyShell_Impl( nShell - nShellCount );
    2112           0 :     return true;
    2113             : }
    2114             : 
    2115        6520 : void SfxDispatcher::RemoveShell_Impl( SfxShell& rShell )
    2116             : {
    2117        6520 :     Flush();
    2118             : 
    2119        6520 :     sal_uInt16 nCount = pImp->aStack.size();
    2120       18488 :     for ( sal_uInt16 n=0; n<nCount; ++n )
    2121             :     {
    2122       18488 :         if ( pImp->aStack[n] == &rShell )
    2123             :         {
    2124        6520 :             pImp->aStack.erase( pImp->aStack.begin() + n );
    2125        6520 :             rShell.SetDisableFlags( 0 );
    2126        6520 :             rShell.DoDeactivate_Impl(pImp->pFrame, true);
    2127        6520 :             break;
    2128             :         }
    2129             :     }
    2130             : 
    2131        6520 :     if ( !SfxGetpApp()->IsDowning() )
    2132             :     {
    2133        6520 :         pImp->bUpdated = false;
    2134        6520 :         pImp->pCachedServ1 = 0;
    2135        6520 :         pImp->pCachedServ2 = 0;
    2136        6520 :         InvalidateBindings_Impl(true);
    2137             :     }
    2138        6520 : }
    2139             : 
    2140       34775 : void SfxDispatcher::InvalidateBindings_Impl( bool bModify )
    2141             : {
    2142             :     // App-Dispatcher?
    2143       34775 :     if ( IsAppDispatcher() )
    2144             :     {
    2145         471 :         for ( SfxViewFrame *pFrame = SfxViewFrame::GetFirst();
    2146             :                 pFrame;
    2147             :                 pFrame = SfxViewFrame::GetNext( *pFrame ) )
    2148           0 :             pFrame->GetBindings().InvalidateAll(bModify);
    2149             :     }
    2150             :     else
    2151             :     {
    2152       34304 :         SfxDispatcher *pDisp = GetBindings()->GetDispatcher_Impl();
    2153       68608 :         while ( pDisp )
    2154             :         {
    2155       34304 :             if ( pDisp == this )
    2156             :             {
    2157       34304 :                 GetBindings()->InvalidateAll( bModify );
    2158       34304 :                 break;
    2159             :             }
    2160             : 
    2161           0 :             pDisp = pDisp->pImp->pParent;
    2162             :         }
    2163             :     }
    2164       34775 : }
    2165             : 
    2166           0 : bool SfxDispatcher::IsUpdated_Impl() const
    2167             : {
    2168           0 :     return pImp->bUpdated;
    2169             : }
    2170             : 
    2171       11046 : void SfxDispatcher::SetDisableFlags( sal_uInt32 nFlags )
    2172             : {
    2173       11046 :     pImp->nDisableFlags = nFlags;
    2174       44234 :     for ( SfxShellStack_Impl::reverse_iterator it = pImp->aStack.rbegin(); it != pImp->aStack.rend(); ++it )
    2175       33188 :         (*it)->SetDisableFlags( nFlags );
    2176       11046 : }
    2177             : 
    2178       49196 : sal_uInt32 SfxDispatcher::GetDisableFlags() const
    2179             : {
    2180       49196 :     return pImp->nDisableFlags;
    2181             : }
    2182             : 
    2183           0 : SfxModule* SfxDispatcher::GetModule() const
    2184             : {
    2185           0 :     for ( sal_uInt16 nShell = 0;; ++nShell )
    2186             :     {
    2187           0 :         SfxShell *pSh = GetShell(nShell);
    2188           0 :         if ( pSh == NULL )
    2189           0 :             return 0;
    2190           0 :         if ( pSh->ISA(SfxModule) )
    2191           0 :             return static_cast<SfxModule*>(pSh);
    2192           0 :     }
    2193         951 : }
    2194             : 
    2195             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10