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

Generated by: LCOV version 1.10