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

Generated by: LCOV version 1.11