LCOV - code coverage report
Current view: top level - sfx2/source/control - bindings.cxx (source / functions) Hit Total Coverage
Test: commit 10e77ab3ff6f4314137acd6e2702a6e5c1ce1fae Lines: 616 942 65.4 %
Date: 2014-11-03 Functions: 48 67 71.6 %
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 <sal/config.h>
      21             : 
      22             : #include <iomanip>
      23             : 
      24             : #include <boost/unordered_map.hpp>
      25             : #include <sal/log.hxx>
      26             : #include <svl/itempool.hxx>
      27             : #include <svl/itemiter.hxx>
      28             : #include <svl/eitem.hxx>
      29             : #include <svl/aeitem.hxx>
      30             : #include <svl/intitem.hxx>
      31             : #include <svl/stritem.hxx>
      32             : #include <svl/visitem.hxx>
      33             : #include <com/sun/star/util/URLTransformer.hpp>
      34             : #include <com/sun/star/util/XURLTransformer.hpp>
      35             : #include <com/sun/star/frame/XDispatchProviderInterceptor.hpp>
      36             : #include <com/sun/star/frame/XDispatch.hpp>
      37             : #include <com/sun/star/frame/XDispatchProvider.hpp>
      38             : #include <com/sun/star/frame/XStatusListener.hpp>
      39             : #include <com/sun/star/frame/FrameSearchFlag.hpp>
      40             : #include <com/sun/star/frame/XDispatchProviderInterception.hpp>
      41             : #include <com/sun/star/frame/FeatureStateEvent.hpp>
      42             : #include <com/sun/star/frame/DispatchDescriptor.hpp>
      43             : #include <com/sun/star/frame/XController.hpp>
      44             : #include <comphelper/processfactory.hxx>
      45             : #include "itemdel.hxx"
      46             : 
      47             : //Includes below due to nInReschedule
      48             : #include "appdata.hxx"
      49             : #include <sfx2/bindings.hxx>
      50             : #include <sfx2/msg.hxx>
      51             : #include "statcach.hxx"
      52             : #include <sfx2/ctrlitem.hxx>
      53             : #include <sfx2/app.hxx>
      54             : #include <sfx2/dispatch.hxx>
      55             : #include <sfx2/request.hxx>
      56             : #include <sfx2/objface.hxx>
      57             : #include "sfxtypes.hxx"
      58             : #include "workwin.hxx"
      59             : #include <sfx2/unoctitm.hxx>
      60             : #include <sfx2/sfx.hrc>
      61             : #include <sfx2/sfxuno.hxx>
      62             : #include <sfx2/viewfrm.hxx>
      63             : #include <sfx2/objsh.hxx>
      64             : #include <sfx2/msgpool.hxx>
      65             : 
      66             : #include <com/sun/star/frame/XModuleManager.hpp>
      67             : #include <boost/scoped_array.hpp>
      68             : #include <boost/scoped_ptr.hpp>
      69             : 
      70             : using namespace ::com::sun::star;
      71             : using namespace ::com::sun::star::uno;
      72             : using namespace ::com::sun::star::util;
      73             : 
      74             : static sal_uInt16 nTimeOut = 300;
      75             : 
      76             : #define TIMEOUT_FIRST       nTimeOut
      77             : #define TIMEOUT_UPDATING     20
      78             : #define TIMEOUT_IDLE       2500
      79             : 
      80             : typedef boost::unordered_map< sal_uInt16, bool > InvalidateSlotMap;
      81             : 
      82             : 
      83             : 
      84             : typedef std::vector<SfxStateCache*> SfxStateCacheArr_Impl;
      85             : 
      86             : 
      87             : 
      88           0 : class SfxAsyncExec_Impl
      89             : {
      90             :     ::com::sun::star::util::URL aCommand;
      91             :     ::com::sun::star::uno::Reference< ::com::sun::star::frame::XDispatch > xDisp;
      92             :     Timer           aTimer;
      93             : 
      94             : public:
      95             : 
      96           0 :     SfxAsyncExec_Impl( const ::com::sun::star::util::URL& rCmd, const ::com::sun::star::uno::Reference< ::com::sun::star::frame::XDispatch >& rDisp )
      97             :         : aCommand( rCmd )
      98           0 :         , xDisp( rDisp )
      99             :     {
     100           0 :         aTimer.SetTimeoutHdl( LINK(this, SfxAsyncExec_Impl, TimerHdl) );
     101           0 :         aTimer.SetTimeout( 0 );
     102           0 :         aTimer.Start();
     103           0 :     }
     104             : 
     105             :     DECL_LINK( TimerHdl, Timer*);
     106             : };
     107             : 
     108           0 : IMPL_LINK(SfxAsyncExec_Impl, TimerHdl, Timer*, pTimer)
     109             : {
     110             :     (void)pTimer; // unused
     111           0 :     aTimer.Stop();
     112             : 
     113           0 :     Sequence<beans::PropertyValue> aSeq;
     114           0 :     xDisp->dispatch( aCommand, aSeq );
     115             : 
     116           0 :     delete this;
     117           0 :     return 0L;
     118             : }
     119             : 
     120       11030 : class SfxBindings_Impl
     121             : {
     122             : public:
     123             :     ::com::sun::star::uno::Reference< ::com::sun::star::frame::XDispatchRecorder > xRecorder;
     124             :     ::com::sun::star::uno::Reference< ::com::sun::star::frame::XDispatchProvider >  xProv;
     125             :     SfxUnoControllerArr_Impl*
     126             :                             pUnoCtrlArr;
     127             :     SfxWorkWindow*          pWorkWin;
     128             :     SfxBindings*            pSubBindings;
     129             :     SfxBindings*            pSuperBindings;
     130             :     SfxStateCacheArr_Impl*  pCaches;        // One chache for each binding
     131             :     sal_uInt16              nCachedFunc1;   // index for the last one called
     132             :     sal_uInt16              nCachedFunc2;   // index for the second last called
     133             :     sal_uInt16              nMsgPos;        // Message-Position relative the one to be updated
     134             :     SfxPopupAction          ePopupAction;   // Checked in DeleteFloatinWindow()
     135             :     bool                bContextChanged;
     136             :     bool                bMsgDirty;      // Has a MessageServer been invalidated?
     137             :     bool                bAllMsgDirty;   //  Has a MessageServer been invalidated?
     138             :     bool                bAllDirty;      // After InvalidateAll
     139             :     bool                bCtrlReleased;  // while EnterRegistrations
     140             :     AutoTimer               aTimer;         // for volatile Slots
     141             :     bool                bInUpdate;      // for Assertions
     142             :     bool                bInNextJob;     // for Assertions
     143             :     bool                bFirstRound;    // First round in Update
     144             :     sal_uInt16              nFirstShell;    // Shell, the first round is preferred
     145             :     sal_uInt16              nOwnRegLevel;   // Counts the real Locks, exept those of the Super Bindings
     146             :     InvalidateSlotMap       m_aInvalidateSlots; // store slots which are invalidated while in update
     147             : };
     148             : 
     149        5516 : SfxBindings::SfxBindings()
     150        5516 : :   pImp(new SfxBindings_Impl),
     151             :     pDispatcher(0),
     152       11032 :     nRegLevel(1)    // first becomes 0, when the Dispatcher is set
     153             : {
     154        5516 :     pImp->nMsgPos = 0;
     155        5516 :     pImp->bAllMsgDirty = true;
     156        5516 :     pImp->bContextChanged = false;
     157        5516 :     pImp->bMsgDirty = true;
     158        5516 :     pImp->bAllDirty = true;
     159        5516 :     pImp->ePopupAction = SFX_POPUP_DELETE;
     160        5516 :     pImp->nCachedFunc1 = 0;
     161        5516 :     pImp->nCachedFunc2 = 0;
     162        5516 :     pImp->bCtrlReleased = false;
     163        5516 :     pImp->bFirstRound = false;
     164        5516 :     pImp->bInNextJob = false;
     165        5516 :     pImp->bInUpdate = false;
     166        5516 :     pImp->pSubBindings = NULL;
     167        5516 :     pImp->pSuperBindings = NULL;
     168        5516 :     pImp->pWorkWin = NULL;
     169        5516 :     pImp->pUnoCtrlArr = NULL;
     170        5516 :     pImp->nOwnRegLevel = nRegLevel;
     171             : 
     172             :     // all caches are valid (no pending invalidate-job)
     173             :     // create the list of caches
     174        5516 :     pImp->pCaches = new SfxStateCacheArr_Impl;
     175        5516 :     pImp->aTimer.SetTimeoutHdl( LINK(this, SfxBindings, NextJob_Impl) );
     176        5516 : }
     177             : 
     178             : 
     179             : 
     180       16534 : SfxBindings::~SfxBindings()
     181             : 
     182             : /*  [Description]
     183             : 
     184             :     Destructor of the SfxBindings class. The one, for each <SfxApplication>
     185             :     existing Instance is automatically destroyed by the <SfxApplication>
     186             :     after the execution of <SfxApplication::Exit()>.
     187             : 
     188             :     The still existing <SfxControllerItem> instances, which are registered
     189             :     by the SfxBindings instance, are automatically destroyed in the Destructor.
     190             :     These are usually the Floating-Toolboxen, Value-Sets
     191             :     etc. Arrays of SfxControllerItems may at this time no longer exist.
     192             : */
     193             : 
     194             : {
     195             :     // The SubBindings should not be locked!
     196        5514 :     pImp->pSubBindings = NULL;
     197             : 
     198        5514 :     ENTERREGISTRATIONS();
     199             : 
     200        5514 :     pImp->aTimer.Stop();
     201        5514 :     DeleteControllers_Impl();
     202             : 
     203             :     // Delete Caches
     204        5514 :     for(SfxStateCacheArr_Impl::const_iterator it = pImp->pCaches->begin(); it != pImp->pCaches->end(); ++it)
     205           0 :         delete *it;
     206             : 
     207        5514 :     DELETEZ( pImp->pWorkWin );
     208             : 
     209        5514 :     delete pImp->pCaches;
     210        5514 :     delete pImp;
     211       11020 : }
     212             : 
     213             : 
     214             : 
     215        5514 : void SfxBindings::DeleteControllers_Impl()
     216             : {
     217             :     // in the first round delete SfxPopupWindows
     218        5514 :     sal_uInt16 nCount = pImp->pCaches->size();
     219             :     sal_uInt16 nCache;
     220      192785 :     for ( nCache = 0; nCache < nCount; ++nCache )
     221             :     {
     222             :         // Remember were you are
     223      187271 :         SfxStateCache *pCache = (*pImp->pCaches)[nCache];
     224      187271 :         sal_uInt16 nSlotId = pCache->GetId();
     225             : 
     226             :         // Delete SfxPopupWindow
     227      187271 :         pCache->DeleteFloatingWindows();
     228             : 
     229             :         // Re-align, because the cache may have been reduced
     230      187271 :         sal_uInt16 nNewCount = pImp->pCaches->size();
     231      187271 :         if ( nNewCount < nCount )
     232             :         {
     233           0 :             nCache = GetSlotPos(nSlotId);
     234           0 :             if ( nCache >= nNewCount ||
     235           0 :                  nSlotId != (*pImp->pCaches)[nCache]->GetId() )
     236           0 :                 --nCache;
     237           0 :             nCount = nNewCount;
     238             :         }
     239             :     }
     240             : 
     241             :     // Delete all Caches
     242      192785 :     for ( nCache = pImp->pCaches->size(); nCache > 0; --nCache )
     243             :     {
     244             :         // Get Cache via ::com::sun::star::sdbcx::Index
     245      187271 :         SfxStateCache *pCache = (*pImp->pCaches)[ nCache-1 ];
     246             : 
     247             :         // unbind all controllers in the cache
     248             :         SfxControllerItem *pNext;
     249      187271 :         for ( SfxControllerItem *pCtrl = pCache->GetItemLink();
     250             :               pCtrl; pCtrl = pNext )
     251             :         {
     252           0 :             pNext = pCtrl->GetItemLink();
     253           0 :             pCtrl->UnBind();
     254             :         }
     255             : 
     256      187271 :         if ( pCache->GetInternalController() )
     257      130227 :             pCache->GetInternalController()->UnBind();
     258             : 
     259             :         // Delete Cache
     260      187271 :         if( nCache-1 < (sal_uInt16) pImp->pCaches->size() )
     261      187271 :             delete (*pImp->pCaches)[nCache-1];
     262      187271 :         pImp->pCaches->erase(pImp->pCaches->begin()+ nCache - 1);
     263             :     }
     264             : 
     265        5514 :     if( pImp->pUnoCtrlArr )
     266             :     {
     267           0 :         sal_uInt16 nCtrlCount = pImp->pUnoCtrlArr->size();
     268           0 :         for ( sal_uInt16 n=nCtrlCount; n>0; n-- )
     269             :         {
     270           0 :             SfxUnoControllerItem *pCtrl = (*pImp->pUnoCtrlArr)[n-1];
     271           0 :             pCtrl->ReleaseBindings();
     272             :         }
     273             : 
     274             :         DBG_ASSERT( !pImp->pUnoCtrlArr->size(), "Do not remove UnoControllerItems!" );
     275           0 :         DELETEZ( pImp->pUnoCtrlArr );
     276             :     }
     277        5514 : }
     278             : 
     279             : 
     280             : 
     281           4 : void SfxBindings::HidePopups( bool bHide )
     282             : {
     283             :     // Hide SfxPopupWindows
     284           4 :     HidePopupCtrls_Impl( bHide );
     285           4 :     SfxBindings *pSub = pImp->pSubBindings;
     286           8 :     while ( pSub )
     287             :     {
     288           0 :         pImp->pSubBindings->HidePopupCtrls_Impl( bHide );
     289           0 :         pSub = pSub->pImp->pSubBindings;
     290             :     }
     291             : 
     292             :     // Hide SfxChildWindows
     293             :     DBG_ASSERT( pDispatcher, "HidePopups not allowed without dispatcher" );
     294           4 :     if ( pImp->pWorkWin )
     295           4 :         pImp->pWorkWin->HidePopups_Impl( bHide, true );
     296           4 : }
     297             : 
     298       10880 : void SfxBindings::HidePopupCtrls_Impl( bool bHide )
     299             : {
     300       10880 :     if ( bHide )
     301             :     {
     302             :         // Hide SfxPopupWindows
     303        5440 :         pImp->ePopupAction = SFX_POPUP_HIDE;
     304             :     }
     305             :     else
     306             :     {
     307             :         // Show SfxPopupWindows
     308        5440 :         pImp->ePopupAction = SFX_POPUP_SHOW;
     309             :     }
     310             : 
     311      297271 :     for(SfxStateCacheArr_Impl::const_iterator it = pImp->pCaches->begin(); it != pImp->pCaches->end(); ++it)
     312      286391 :         (*it)->DeleteFloatingWindows();
     313       10880 :     pImp->ePopupAction = SFX_POPUP_DELETE;
     314       10880 : }
     315             : 
     316             : 
     317             : 
     318       12771 : void SfxBindings::Update_Impl
     319             : (
     320             :     SfxStateCache*  pCache      // The up to date SfxStatusCache
     321             : )
     322             : {
     323       12771 :     if( pCache->GetDispatch().is() && pCache->GetItemLink() )
     324             :     {
     325           0 :         pCache->SetCachedState(true);
     326           0 :         if ( !pCache->GetInternalController() )
     327           0 :             return;
     328             :     }
     329             : 
     330       12771 :     if ( !pDispatcher )
     331           0 :         return;
     332             : 
     333             :     // gather together all with the same status method which are dirty
     334       12771 :     SfxDispatcher &rDispat = *pDispatcher;
     335       12771 :     const SfxSlot *pRealSlot = 0;
     336       12771 :     const SfxSlotServer* pMsgServer = 0;
     337       12771 :     SfxFoundCacheArr_Impl aFound;
     338       12771 :     SfxItemSet *pSet = CreateSet_Impl( pCache, pRealSlot, &pMsgServer, aFound );
     339       12771 :     bool bUpdated = false;
     340       12771 :     if ( pSet )
     341             :     {
     342             :         // Query Status
     343       11428 :         if ( rDispat._FillState( *pMsgServer, *pSet, pRealSlot ) )
     344             :         {
     345             :             // Post Status
     346             :             const SfxInterface *pInterface =
     347       11428 :                 rDispat.GetShell(pMsgServer->GetShellLevel())->GetInterface();
     348       48228 :             for ( sal_uInt16 nPos = 0; nPos < aFound.size(); ++nPos )
     349             :             {
     350       36800 :                 const SfxFoundCache_Impl& rFound = aFound[nPos];
     351       36800 :                 sal_uInt16 nWhich = rFound.nWhichId;
     352       36800 :                 const SfxPoolItem *pItem = 0;
     353       36800 :                 SfxItemState eState = pSet->GetItemState(nWhich, true, &pItem);
     354       36800 :                 if ( eState == SfxItemState::DEFAULT && SfxItemPool::IsWhich(nWhich) )
     355        1198 :                     pItem = &pSet->Get(nWhich);
     356       36800 :                 UpdateControllers_Impl( pInterface, aFound[nPos], pItem, eState );
     357             :             }
     358       11428 :             bUpdated = true;
     359             :         }
     360             : 
     361       11428 :         delete pSet;
     362             :     }
     363             : 
     364       12771 :     if ( !bUpdated && pCache )
     365             :     {
     366             :         // When pCache == NULL and no SlotServer
     367             :         // (for example due to locked Dispatcher! ),
     368             :         // obviously do not try to update
     369             :         SfxFoundCache_Impl aFoundCache(
     370        1343 :                             pCache->GetId(), 0,
     371        2686 :                             pRealSlot, pCache );
     372        1343 :         UpdateControllers_Impl( 0, aFoundCache, 0, SfxItemState::DISABLED);
     373       12771 :     }
     374             : }
     375             : 
     376             : 
     377             : 
     378        3470 : void SfxBindings::InvalidateSlotsInMap_Impl()
     379             : {
     380        3470 :     InvalidateSlotMap::const_iterator pIter = pImp->m_aInvalidateSlots.begin();
     381        6940 :     while ( pIter != pImp->m_aInvalidateSlots.end() )
     382             :     {
     383           0 :         Invalidate( pIter->first );
     384           0 :         ++pIter;
     385             :     }
     386        3470 :     pImp->m_aInvalidateSlots.clear();
     387        3470 : }
     388             : 
     389             : 
     390             : 
     391           0 : void SfxBindings::AddSlotToInvalidateSlotsMap_Impl( sal_uInt16 nId )
     392             : {
     393           0 :     pImp->m_aInvalidateSlots[nId] = true;
     394           0 : }
     395             : 
     396             : 
     397             : 
     398        3696 : void SfxBindings::Update
     399             : (
     400             :     sal_uInt16      nId     // the bound and up-to-date Slot-Id
     401             : )
     402             : {
     403             :     DBG_ASSERT( pImp->pCaches != 0, "SfxBindings not initialized" );
     404             : 
     405        3696 :     if ( pDispatcher )
     406        3696 :         pDispatcher->Flush();
     407             : 
     408        3696 :     if ( pImp->pSubBindings )
     409           0 :         pImp->pSubBindings->Update( nId );
     410             : 
     411        3696 :     SfxStateCache* pCache = GetStateCache( nId );
     412        3696 :     if ( pCache )
     413             :     {
     414        3470 :         pImp->bInUpdate = true;
     415        3470 :         if ( pImp->bMsgDirty )
     416             :         {
     417         982 :             UpdateSlotServer_Impl();
     418         982 :             pCache = GetStateCache( nId );
     419             :         }
     420             : 
     421        3470 :         if (pCache)
     422             :         {
     423        3470 :             bool bInternalUpdate = true;
     424        3470 :             if( pCache->GetDispatch().is() && pCache->GetItemLink() )
     425             :             {
     426           0 :                 pCache->SetCachedState(true);
     427           0 :                 bInternalUpdate = ( pCache->GetInternalController() != 0 );
     428             :             }
     429             : 
     430        3470 :             if ( bInternalUpdate )
     431             :             {
     432             :                 // Query Status
     433        3470 :                 const SfxSlotServer* pMsgServer = pDispatcher ? pCache->GetSlotServer(*pDispatcher, pImp->xProv) : NULL;
     434        4468 :                 if ( !pCache->IsControllerDirty() &&
     435         998 :                     ( !pMsgServer ||
     436         998 :                     !pMsgServer->GetSlot()->IsMode(SFX_SLOT_VOLATILE) ) )
     437             :                 {
     438         998 :                     pImp->bInUpdate = false;
     439         998 :                     InvalidateSlotsInMap_Impl();
     440         998 :                     return;
     441             :                 }
     442        2472 :                 if (!pMsgServer)
     443             :                 {
     444           0 :                     pCache->SetState(SfxItemState::DISABLED, 0);
     445           0 :                     pImp->bInUpdate = false;
     446           0 :                     InvalidateSlotsInMap_Impl();
     447           0 :                     return;
     448             :                 }
     449             : 
     450        2472 :                 Update_Impl(pCache);
     451             :             }
     452             : 
     453        2472 :             pImp->bAllDirty = false;
     454             :         }
     455             : 
     456        2472 :         pImp->bInUpdate = false;
     457        2472 :         InvalidateSlotsInMap_Impl();
     458             :     }
     459             : }
     460             : 
     461             : 
     462             : 
     463           0 : void SfxBindings::Update()
     464             : {
     465             :     DBG_ASSERT( pImp->pCaches != 0, "SfxBindings not initialized" );
     466             : 
     467           0 :     if ( pImp->pSubBindings )
     468           0 :         pImp->pSubBindings->Update();
     469             : 
     470           0 :     if ( pDispatcher )
     471             :     {
     472           0 :         if ( nRegLevel )
     473           0 :             return;
     474             : 
     475           0 :         pImp->bInUpdate = true;
     476           0 :         pDispatcher->Flush();
     477           0 :         pDispatcher->Update_Impl();
     478           0 :         while ( !NextJob_Impl(0) )
     479             :             ; // loop
     480           0 :         pImp->bInUpdate = false;
     481           0 :         InvalidateSlotsInMap_Impl();
     482             :     }
     483             : }
     484             : 
     485             : 
     486             : 
     487           0 : void SfxBindings::SetState
     488             : (
     489             :     const SfxItemSet&   rSet    // status values to be set
     490             : )
     491             : {
     492             :     // when locked then only invalidate
     493           0 :     if ( nRegLevel )
     494             :     {
     495           0 :         SfxItemIter aIter(rSet);
     496           0 :         for ( const SfxPoolItem *pItem = aIter.FirstItem();
     497             :               pItem;
     498             :               pItem = aIter.NextItem() )
     499           0 :             Invalidate( pItem->Which() );
     500             :     }
     501             :     else
     502             :     {
     503             :         // Status may be accepted only if all slot-pointers are set
     504           0 :         if ( pImp->bMsgDirty )
     505           0 :             UpdateSlotServer_Impl();
     506             : 
     507             :         // Iterate over the itemset, update if the slot bound
     508             :         //! Bug: Use WhichIter and possibly send VoidItems up
     509           0 :         SfxItemIter aIter(rSet);
     510           0 :         for ( const SfxPoolItem *pItem = aIter.FirstItem();
     511             :               pItem;
     512             :               pItem = aIter.NextItem() )
     513             :         {
     514             :             SfxStateCache* pCache =
     515           0 :                     GetStateCache( rSet.GetPool()->GetSlotId(pItem->Which()) );
     516           0 :             if ( pCache )
     517             :             {
     518             :                 // Update status
     519           0 :                 if ( !pCache->IsControllerDirty() )
     520           0 :                     pCache->Invalidate(false);
     521           0 :                 pCache->SetState( SfxItemState::DEFAULT, pItem );
     522             : 
     523             :                 //! Not implemented: Updates from EnumSlots via master slots
     524             :             }
     525           0 :         }
     526             :     }
     527           0 : }
     528             : 
     529             : 
     530             : 
     531         502 : void SfxBindings::SetState
     532             : (
     533             :     const SfxPoolItem&  rItem   // Status value to be set
     534             : )
     535             : {
     536         502 :     if ( nRegLevel )
     537             :     {
     538          24 :         Invalidate( rItem.Which() );
     539             :     }
     540             :     else
     541             :     {
     542             :         // Status may be accepted only if all slot-pointers are set
     543         478 :         if ( pImp->bMsgDirty )
     544         227 :             UpdateSlotServer_Impl();
     545             : 
     546             :         //update if the slot bound
     547             :         DBG_ASSERT( SfxItemPool::IsSlot( rItem.Which() ),
     548             :                     "cannot set items with which-id" );
     549         478 :         SfxStateCache* pCache = GetStateCache( rItem.Which() );
     550         478 :         if ( pCache )
     551             :         {
     552             :             // Update Status
     553         252 :             if ( !pCache->IsControllerDirty() )
     554         117 :                 pCache->Invalidate(false);
     555         252 :             pCache->SetState( SfxItemState::DEFAULT, &rItem );
     556             : 
     557             :             //! Not implemented: Updates from EnumSlots via master slots
     558             :         }
     559             :     }
     560         502 : }
     561             : 
     562             : 
     563             : 
     564             : 
     565           0 : SfxStateCache* SfxBindings::GetAnyStateCache_Impl( sal_uInt16 nId )
     566             : {
     567           0 :     SfxStateCache* pCache = GetStateCache( nId );
     568           0 :     if ( !pCache && pImp->pSubBindings )
     569           0 :         return pImp->pSubBindings->GetAnyStateCache_Impl( nId );
     570           0 :     return pCache;
     571             : }
     572             : 
     573      465608 : SfxStateCache* SfxBindings::GetStateCache
     574             : (
     575             :     sal_uInt16   nId   /*  Slot-Id, which SfxStatusCache is to be found */
     576             : )
     577             : {
     578      465608 :     return GetStateCache(nId, 0);
     579             : }
     580             : 
     581      657897 : SfxStateCache* SfxBindings::GetStateCache
     582             : (
     583             :     sal_uInt16   nId,   /*  Slot-Id, which SfxStatusCache is to be found */
     584             :     sal_uInt16*  pPos   /*  NULL for instance the position from which the
     585             :                            bindings are to be searched binary. Returns the
     586             :                            position back for where the nId was found,
     587             :                            or where it was inserted. */
     588             : )
     589             : {
     590             :     DBG_ASSERT( pImp->pCaches != 0, "SfxBindings not initialized" );
     591             :     // is the specified function bound?
     592      657897 :     const sal_uInt16 nStart = ( pPos ? *pPos : 0 );
     593      657897 :     const sal_uInt16 nPos = GetSlotPos( nId, nStart );
     594             : 
     595     1298204 :     if ( nPos < pImp->pCaches->size() &&
     596      640307 :          (*pImp->pCaches)[nPos]->GetId() == nId )
     597             :     {
     598      367826 :         if ( pPos )
     599       28675 :             *pPos = nPos;
     600      367826 :         return (*pImp->pCaches)[nPos];
     601             :     }
     602      290071 :     return 0;
     603             : }
     604             : 
     605             : 
     606             : 
     607      103837 : void SfxBindings::InvalidateAll
     608             : (
     609             :     bool  bWithMsg  /* true   Mark Slot Server as invalid
     610             :                        false  Slot Server remains valid */
     611             : )
     612             : {
     613             :     DBG_ASSERT( !pImp->bInUpdate, "SfxBindings::Invalidate while in update" );
     614             : 
     615      103837 :     if ( pImp->pSubBindings )
     616          30 :         pImp->pSubBindings->InvalidateAll( bWithMsg );
     617             : 
     618             :     // everything is already set dirty or downing => nothing to do
     619      300597 :     if ( !pDispatcher ||
     620      197932 :          ( pImp->bAllDirty && ( !bWithMsg || pImp->bAllMsgDirty ) ) ||
     621        2616 :          SfxGetpApp()->IsDowning() )
     622             :     {
     623      205058 :         return;
     624             :     }
     625             : 
     626        2616 :     pImp->bAllMsgDirty = pImp->bAllMsgDirty || bWithMsg;
     627        2616 :     pImp->bMsgDirty = pImp->bMsgDirty || pImp->bAllMsgDirty || bWithMsg;
     628        2616 :     pImp->bAllDirty = true;
     629             : 
     630      261858 :     for ( sal_uInt16 n = 0; n < pImp->pCaches->size(); ++n )
     631      259242 :         (*pImp->pCaches)[n]->Invalidate(bWithMsg);
     632             : 
     633        2616 :     pImp->nMsgPos = 0;
     634        2616 :     if ( !nRegLevel )
     635             :     {
     636        1022 :         pImp->aTimer.Stop();
     637        1022 :         pImp->aTimer.SetTimeout(TIMEOUT_FIRST);
     638        1022 :         pImp->aTimer.Start();
     639             :     }
     640             : }
     641             : 
     642             : 
     643             : 
     644       55972 : void SfxBindings::Invalidate
     645             : (
     646             :     const sal_uInt16* pIds /* numerically sorted NULL-terminated array of
     647             :                               slot IDs (individual, not as a couple!) */
     648             : )
     649             : {
     650       55972 :     if ( pImp->bInUpdate )
     651             :     {
     652           0 :         sal_Int32 i = 0;
     653           0 :         while ( pIds[i] != 0 )
     654           0 :             AddSlotToInvalidateSlotsMap_Impl( pIds[i++] );
     655             : 
     656           0 :         if ( pImp->pSubBindings )
     657           0 :             pImp->pSubBindings->Invalidate( pIds );
     658           0 :         return;
     659             :     }
     660             : 
     661       55972 :     if ( pImp->pSubBindings )
     662           0 :         pImp->pSubBindings->Invalidate( pIds );
     663             : 
     664             :     // everything is already set dirty or downing => nothing to do
     665       55972 :     if ( !pDispatcher || pImp->bAllDirty || SfxGetpApp()->IsDowning() )
     666       55766 :         return;
     667             : 
     668             :     // Search binary in always smaller areas
     669        5454 :     for ( sal_uInt16 n = GetSlotPos(*pIds);
     670        2727 :           *pIds && n < pImp->pCaches->size();
     671        2521 :           n = GetSlotPos(*pIds, n) )
     672             :     {
     673             :         // If SID is ever bound, then invalidate the cache
     674        2727 :         SfxStateCache *pCache = (*pImp->pCaches)[n];
     675        2727 :         if ( pCache->GetId() == *pIds )
     676        2665 :             pCache->Invalidate(false);
     677             : 
     678             :         // Next SID
     679        2727 :         if ( !*++pIds )
     680         206 :             break;
     681             :         DBG_ASSERT( *pIds > *(pIds-1), "pIds unsorted" );
     682             :     }
     683             : 
     684             :     // if not enticed to start update timer
     685         206 :     pImp->nMsgPos = 0;
     686         206 :     if ( !nRegLevel )
     687             :     {
     688         206 :         pImp->aTimer.Stop();
     689         206 :         pImp->aTimer.SetTimeout(TIMEOUT_FIRST);
     690         206 :         pImp->aTimer.Start();
     691             :     }
     692             : }
     693             : 
     694             : 
     695             : 
     696        1058 : void SfxBindings::InvalidateShell
     697             : (
     698             :     const SfxShell&  rSh,  /* <SfxShell>, which Slot-Ids should be
     699             :                               invalidated */
     700             :     bool             bDeep /* true
     701             :                               also inherited slot IDs of SfxShell are invalidert
     702             : 
     703             :                               false
     704             :                               the inherited and not overloaded Slot-Ids were
     705             :                               invalidiert */
     706             :                              // for now always bDeep
     707             : )
     708             : {
     709             :     DBG_ASSERT( !pImp->bInUpdate, "SfxBindings::Invalidate while in update" );
     710             : 
     711        1058 :     if ( pImp->pSubBindings )
     712           0 :         pImp->pSubBindings->InvalidateShell( rSh, bDeep );
     713             : 
     714        1058 :     if ( !pDispatcher || pImp->bAllDirty || SfxGetpApp()->IsDowning() )
     715        1051 :         return;
     716             : 
     717             :     // flush now already, it is done in GetShellLevel (rsh) anyway,
     718             :     // important so that is set correctly: pimp-> ball(Msg)Dirty
     719           7 :     pDispatcher->Flush();
     720             : 
     721          21 :     if ( !pDispatcher ||
     722          14 :          ( pImp->bAllDirty && pImp->bAllMsgDirty ) ||
     723           7 :          SfxGetpApp()->IsDowning() )
     724             :     {
     725             :         // if the next one is anyway, then all the servers are collected
     726           0 :         return;
     727             :     }
     728             : 
     729             :     // Find Level
     730           7 :     sal_uInt16 nLevel = pDispatcher->GetShellLevel(rSh);
     731           7 :     if ( nLevel != USHRT_MAX )
     732             :     {
     733         684 :         for ( sal_uInt16 n = 0; n < pImp->pCaches->size(); ++n )
     734             :         {
     735         677 :             SfxStateCache *pCache = (*pImp->pCaches)[n];
     736             :             const SfxSlotServer *pMsgServer =
     737         677 :                 pCache->GetSlotServer(*pDispatcher, pImp->xProv);
     738         677 :             if ( pMsgServer && pMsgServer->GetShellLevel() == nLevel )
     739         315 :                 pCache->Invalidate(false);
     740             :         }
     741           7 :         pImp->nMsgPos = 0;
     742           7 :         if ( !nRegLevel )
     743             :         {
     744           7 :             pImp->aTimer.Stop();
     745           7 :             pImp->aTimer.SetTimeout(TIMEOUT_FIRST);
     746           7 :             pImp->aTimer.Start();
     747           7 :             pImp->bFirstRound = true;
     748           7 :             pImp->nFirstShell = nLevel;
     749             :         }
     750             :     }
     751             : }
     752             : 
     753             : 
     754             : 
     755      493821 : void SfxBindings::Invalidate
     756             : (
     757             :     sal_uInt16 nId              // Status value to be set
     758             : )
     759             : {
     760      493821 :     if ( pImp->bInUpdate )
     761             :     {
     762           0 :         AddSlotToInvalidateSlotsMap_Impl( nId );
     763           0 :         if ( pImp->pSubBindings )
     764           0 :             pImp->pSubBindings->Invalidate( nId );
     765           0 :         return;
     766             :     }
     767             : 
     768      493821 :     if ( pImp->pSubBindings )
     769         112 :         pImp->pSubBindings->Invalidate( nId );
     770             : 
     771      493821 :     if ( !pDispatcher || pImp->bAllDirty || SfxGetpApp()->IsDowning() )
     772      467500 :         return;
     773             : 
     774       26321 :     SfxStateCache* pCache = GetStateCache(nId);
     775       26321 :     if ( pCache )
     776             :     {
     777       15225 :         pCache->Invalidate(false);
     778       15225 :         pImp->nMsgPos = std::min(GetSlotPos(nId), pImp->nMsgPos);
     779       15225 :         if ( !nRegLevel )
     780             :         {
     781       15205 :             pImp->aTimer.Stop();
     782       15205 :             pImp->aTimer.SetTimeout(TIMEOUT_FIRST);
     783       15205 :             pImp->aTimer.Start();
     784             :         }
     785             :     }
     786             : }
     787             : 
     788             : 
     789             : 
     790        4429 : void SfxBindings::Invalidate
     791             : (
     792             :     sal_uInt16  nId,                // Status value to be set
     793             :     bool        bWithItem,          // Clear StateCache?
     794             :     bool        bWithMsg            // Get new SlotServer?
     795             : )
     796             : {
     797             :     DBG_ASSERT( !pImp->bInUpdate, "SfxBindings::Invalidate while in update" );
     798             : 
     799        4429 :     if ( pImp->pSubBindings )
     800           0 :         pImp->pSubBindings->Invalidate( nId, bWithItem, bWithMsg );
     801             : 
     802        4429 :     if ( SfxGetpApp()->IsDowning() )
     803           0 :         return;
     804             : 
     805        4429 :     SfxStateCache* pCache = GetStateCache(nId);
     806        4429 :     if ( pCache )
     807             :     {
     808          18 :         if ( bWithItem )
     809          18 :             pCache->ClearCache();
     810          18 :         pCache->Invalidate(bWithMsg);
     811             : 
     812          18 :         if ( !pDispatcher || pImp->bAllDirty )
     813          12 :             return;
     814             : 
     815           6 :         pImp->nMsgPos = std::min(GetSlotPos(nId), pImp->nMsgPos);
     816           6 :         if ( !nRegLevel )
     817             :         {
     818           6 :             pImp->aTimer.Stop();
     819           6 :             pImp->aTimer.SetTimeout(TIMEOUT_FIRST);
     820           6 :             pImp->aTimer.Start();
     821             :         }
     822             :     }
     823             : }
     824             : 
     825             : 
     826             : 
     827           0 : bool SfxBindings::IsBound( sal_uInt16 nSlotId, sal_uInt16 nStartSearchAt )
     828             : {
     829             :     DBG_ASSERT( pImp->pCaches != 0, "SfxBindings not initialized" );
     830           0 :     return GetStateCache(nSlotId, &nStartSearchAt ) != 0;
     831             : }
     832             : 
     833             : 
     834             : 
     835     1351233 : sal_uInt16 SfxBindings::GetSlotPos( sal_uInt16 nId, sal_uInt16 nStartSearchAt )
     836             : {
     837             :     DBG_ASSERT( pImp->pCaches != 0, "SfxBindings not initialized" );
     838             : 
     839             :     // answer immediately if a function-seek comes repeated
     840     2548649 :     if ( pImp->nCachedFunc1 < pImp->pCaches->size() &&
     841     1197416 :          (*pImp->pCaches)[pImp->nCachedFunc1]->GetId() == nId )
     842             :     {
     843      155407 :         return pImp->nCachedFunc1;
     844             :     }
     845     2243714 :     if ( pImp->nCachedFunc2 < pImp->pCaches->size() &&
     846     1047888 :          (*pImp->pCaches)[pImp->nCachedFunc2]->GetId() == nId )
     847             :     {
     848             :         // swap the caches
     849       26666 :         sal_uInt16 nTemp = pImp->nCachedFunc1;
     850       26666 :         pImp->nCachedFunc1 = pImp->nCachedFunc2;
     851       26666 :         pImp->nCachedFunc2 = nTemp;
     852       26666 :         return pImp->nCachedFunc1;
     853             :     }
     854             : 
     855             :     // binary search, if not found, seek to target-position
     856     1169160 :     if ( pImp->pCaches->size() <= nStartSearchAt )
     857             :     {
     858       17952 :         return 0;
     859             :     }
     860     1151208 :     if ( (sal_uInt16) pImp->pCaches->size() == (nStartSearchAt+1) )
     861             :     {
     862       17112 :         return (*pImp->pCaches)[nStartSearchAt]->GetId() >= nId ? 0 : 1;
     863             :     }
     864     1134096 :     sal_uInt16 nLow = nStartSearchAt;
     865     1134096 :     sal_uInt16 nMid = 0;
     866     1134096 :     sal_uInt16 nHigh = 0;
     867     1134096 :     bool bFound = false;
     868     1134096 :     nHigh = pImp->pCaches->size() - 1;
     869     7861316 :     while ( !bFound && nLow <= nHigh )
     870             :     {
     871     5609604 :         nMid = (nLow + nHigh) >> 1;
     872             :         DBG_ASSERT( nMid < pImp->pCaches->size(), "bsearch is buggy" );
     873     5609604 :         int nDiff = (int) nId - (int) ( ((*pImp->pCaches)[nMid])->GetId() );
     874     5609604 :         if ( nDiff < 0)
     875     2039336 :         {   if ( nMid == 0 )
     876       16480 :                 break;
     877     2022856 :             nHigh = nMid - 1;
     878             :         }
     879     3570268 :         else if ( nDiff > 0 )
     880     2956880 :         {   nLow = nMid + 1;
     881     2956880 :             if ( nLow == 0 )
     882           0 :                 break;
     883             :         }
     884             :         else
     885      613388 :             bFound = true;
     886             :     }
     887     1134096 :     sal_uInt16 nPos = bFound ? nMid : nLow;
     888             :     DBG_ASSERT( nPos <= pImp->pCaches->size(), "" );
     889             :     DBG_ASSERT( nPos == pImp->pCaches->size() ||
     890             :                 nId <= (*pImp->pCaches)[nPos]->GetId(), "" );
     891             :     DBG_ASSERT( nPos == nStartSearchAt ||
     892             :                 nId > (*pImp->pCaches)[nPos-1]->GetId(), "" );
     893             :     DBG_ASSERT( ( (nPos+1) >= (sal_uInt16) pImp->pCaches->size() ) ||
     894             :                 nId < (*pImp->pCaches)[nPos+1]->GetId(), "" );
     895     1134096 :     pImp->nCachedFunc2 = pImp->nCachedFunc1;
     896     1134096 :     pImp->nCachedFunc1 = nPos;
     897     1134096 :     return nPos;
     898             : }
     899             : 
     900      130227 : void SfxBindings::RegisterInternal_Impl( SfxControllerItem& rItem )
     901             : {
     902      130227 :     Register_Impl( rItem, true );
     903             : 
     904      130227 : }
     905             : 
     906      207402 : void SfxBindings::Register( SfxControllerItem& rItem )
     907             : {
     908      207402 :     Register_Impl( rItem, false );
     909      207402 : }
     910             : 
     911      337629 : void SfxBindings::Register_Impl( SfxControllerItem& rItem, bool bInternal )
     912             : {
     913             : //    DBG_ASSERT( nRegLevel > 0, "registration without EnterRegistrations" );
     914             :     DBG_ASSERT( !pImp->bInNextJob, "SfxBindings::Register while status-updating" );
     915             : 
     916             :     // insert new cache if it does not already exist
     917      337629 :     sal_uInt16 nId = rItem.GetId();
     918      337629 :     sal_uInt16 nPos = GetSlotPos(nId);
     919      618582 :     if ( nPos >= pImp->pCaches->size() ||
     920      280953 :          (*pImp->pCaches)[nPos]->GetId() != nId )
     921             :     {
     922      260393 :         SfxStateCache* pCache = new SfxStateCache(nId);
     923      260393 :         pImp->pCaches->insert( pImp->pCaches->begin() + nPos, pCache );
     924             :         DBG_ASSERT( nPos == 0 ||
     925             :                     (*pImp->pCaches)[nPos]->GetId() >
     926             :                         (*pImp->pCaches)[nPos-1]->GetId(), "" );
     927             :         DBG_ASSERT( (nPos == pImp->pCaches->size()-1) ||
     928             :                     (*pImp->pCaches)[nPos]->GetId() <
     929             :                         (*pImp->pCaches)[nPos+1]->GetId(), "" );
     930      260393 :         pImp->bMsgDirty = true;
     931             :     }
     932             : 
     933             :     // enqueue the new binding
     934      337629 :     if ( bInternal )
     935             :     {
     936      130227 :         (*pImp->pCaches)[nPos]->SetInternalController( &rItem );
     937             :     }
     938             :     else
     939             :     {
     940      207402 :         SfxControllerItem *pOldItem = (*pImp->pCaches)[nPos]->ChangeItemLink(&rItem);
     941      207402 :         rItem.ChangeItemLink(pOldItem);
     942             :     }
     943      337629 : }
     944             : 
     945             : 
     946             : 
     947      337749 : void SfxBindings::Release( SfxControllerItem& rItem )
     948             : {
     949             :     DBG_ASSERT( pImp->pCaches != 0, "SfxBindings not initialized" );
     950             :     DBG_ASSERT( !pImp->bInNextJob, "SfxBindings::Release while status-updating" );
     951      337749 :     ENTERREGISTRATIONS();
     952             : 
     953             :     // find the bound function
     954      337749 :     sal_uInt16 nId = rItem.GetId();
     955      337749 :     sal_uInt16 nPos = GetSlotPos(nId);
     956      337749 :     SfxStateCache* pCache = (*pImp->pCaches)[nPos];
     957      337749 :     if ( pCache->GetId() == nId )
     958             :     {
     959      337749 :         if ( pCache->GetInternalController() == &rItem )
     960             :         {
     961      130227 :             pCache->ReleaseInternalController();
     962             :         }
     963             :         else
     964             :         {
     965             :             // is this the first binding in the list?
     966      207522 :             SfxControllerItem* pItem = pCache->GetItemLink();
     967      207522 :             if ( pItem == &rItem )
     968      182638 :                 pCache->ChangeItemLink( rItem.GetItemLink() );
     969             :             else
     970             :             {
     971             :                 // search the binding in the list
     972       49768 :                 while ( pItem && pItem->GetItemLink() != &rItem )
     973           0 :                     pItem = pItem->GetItemLink();
     974             : 
     975             :                 // unlink it if it was found
     976       24884 :                 if ( pItem )
     977       24764 :                     pItem->ChangeItemLink( rItem.GetItemLink() );
     978             :             }
     979             :         }
     980             : 
     981             :         // was this the last controller?
     982      337749 :         if ( pCache->GetItemLink() == 0 && !pCache->GetInternalController() )
     983             :         {
     984      260393 :             pImp->bCtrlReleased = true;
     985             :         }
     986             :     }
     987             : 
     988      337749 :     LEAVEREGISTRATIONS();
     989      337749 : }
     990             : 
     991             : 
     992           0 : const SfxPoolItem* SfxBindings::ExecuteSynchron( sal_uInt16 nId, const SfxPoolItem** ppItems, sal_uInt16 nModi,
     993             :             const SfxPoolItem **ppInternalArgs )
     994             : {
     995             :     DBG_ASSERT( pImp->pCaches != 0, "SfxBindings not initialized" );
     996             : 
     997           0 :     if( !nId || !pDispatcher )
     998           0 :         return NULL;
     999             : 
    1000           0 :     return Execute_Impl( nId, ppItems, nModi, SfxCallMode::SYNCHRON, ppInternalArgs );
    1001             : }
    1002             : 
    1003           0 : bool SfxBindings::Execute( sal_uInt16 nId, const SfxPoolItem** ppItems, sal_uInt16 nModi, SfxCallMode nCallMode,
    1004             :                         const SfxPoolItem **ppInternalArgs )
    1005             : {
    1006             :     DBG_ASSERT( pImp->pCaches != 0, "SfxBindings not initialized" );
    1007             : 
    1008           0 :     if( !nId || !pDispatcher )
    1009           0 :         return false;
    1010             : 
    1011           0 :     const SfxPoolItem* pRet = Execute_Impl( nId, ppItems, nModi, nCallMode, ppInternalArgs );
    1012           0 :     return ( pRet != 0 );
    1013             : }
    1014             : 
    1015           0 : const SfxPoolItem* SfxBindings::Execute_Impl( sal_uInt16 nId, const SfxPoolItem** ppItems, sal_uInt16 nModi, SfxCallMode nCallMode,
    1016             :                         const SfxPoolItem **ppInternalArgs, bool bGlobalOnly )
    1017             : {
    1018           0 :     SfxStateCache *pCache = GetStateCache( nId );
    1019           0 :     if ( !pCache )
    1020             :     {
    1021           0 :         SfxBindings *pBind = pImp->pSubBindings;
    1022           0 :         while ( pBind )
    1023             :         {
    1024           0 :             if ( pBind->GetStateCache( nId ) )
    1025           0 :                 return pBind->Execute_Impl( nId, ppItems, nModi, nCallMode, ppInternalArgs, bGlobalOnly );
    1026           0 :             pBind = pBind->pImp->pSubBindings;
    1027             :         }
    1028             :     }
    1029             : 
    1030           0 :     SfxDispatcher &rDispatcher = *pDispatcher;
    1031           0 :     rDispatcher.Flush();
    1032           0 :     rDispatcher.GetFrame();  // -Wall is this required???
    1033             : 
    1034             :     // get SlotServer (Slot+ShellLevel) and Shell from cache
    1035           0 :     ::boost::scoped_ptr<SfxStateCache> xCache;
    1036           0 :     if ( !pCache )
    1037             :     {
    1038             :         // Execution of non cached slots (Accelerators don't use Controllers)
    1039             :         // slot is uncached, use SlotCache to handle external dispatch providers
    1040           0 :         xCache.reset(new SfxStateCache(nId));
    1041           0 :         pCache = xCache.get();
    1042           0 :         pCache->GetSlotServer( rDispatcher, pImp->xProv );
    1043             :     }
    1044             : 
    1045           0 :     if ( pCache->GetDispatch().is() )
    1046             :     {
    1047             :         DBG_ASSERT( !ppInternalArgs, "Internal args get lost when dispatched!" );
    1048             : 
    1049           0 :         SfxItemPool &rPool = GetDispatcher()->GetFrame()->GetObjectShell()->GetPool();
    1050           0 :         SfxRequest aReq( nId, nCallMode, rPool );
    1051           0 :         aReq.SetModifier( nModi );
    1052           0 :         if( ppItems )
    1053           0 :             while( *ppItems )
    1054           0 :                 aReq.AppendItem( **ppItems++ );
    1055             : 
    1056             :         // cache binds to an external dispatch provider
    1057           0 :         pCache->Dispatch( aReq.GetArgs(), nCallMode == SfxCallMode::SYNCHRON );
    1058           0 :         SfxPoolItem *pVoid = new SfxVoidItem( nId );
    1059           0 :         DeleteItemOnIdle( pVoid );
    1060           0 :         return pVoid;
    1061             :     }
    1062             : 
    1063             :     // slot is handled internally by SfxDispatcher
    1064           0 :     if ( pImp->bMsgDirty )
    1065           0 :         UpdateSlotServer_Impl();
    1066             : 
    1067           0 :     SfxShell *pShell=0;
    1068           0 :     const SfxSlot *pSlot=0;
    1069             : 
    1070           0 :     const SfxSlotServer* pServer = pCache->GetSlotServer( rDispatcher, pImp->xProv );
    1071           0 :     if ( !pServer )
    1072             :     {
    1073           0 :         return NULL;
    1074             :     }
    1075             :     else
    1076             :     {
    1077           0 :         pShell = rDispatcher.GetShell( pServer->GetShellLevel() );
    1078           0 :         pSlot = pServer->GetSlot();
    1079             :     }
    1080             : 
    1081           0 :     if ( bGlobalOnly )
    1082           0 :         if ( !pShell->ISA(SfxModule) && !pShell->ISA(SfxApplication) && !pShell->ISA(SfxViewFrame) )
    1083           0 :             return NULL;
    1084             : 
    1085           0 :     SfxItemPool &rPool = pShell->GetPool();
    1086           0 :     SfxRequest aReq( nId, nCallMode, rPool );
    1087           0 :     aReq.SetModifier( nModi );
    1088           0 :     if( ppItems )
    1089           0 :         while( *ppItems )
    1090           0 :             aReq.AppendItem( **ppItems++ );
    1091           0 :     if ( ppInternalArgs )
    1092             :     {
    1093           0 :         SfxAllItemSet aSet( rPool );
    1094           0 :         for ( const SfxPoolItem **pArg = ppInternalArgs; *pArg; ++pArg )
    1095           0 :             aSet.Put( **pArg );
    1096           0 :         aReq.SetInternalArgs_Impl( aSet );
    1097             :     }
    1098             : 
    1099           0 :     Execute_Impl( aReq, pSlot, pShell );
    1100             : 
    1101           0 :     const SfxPoolItem* pRet = aReq.GetReturnValue();
    1102           0 :     if ( !pRet )
    1103             :     {
    1104           0 :         SfxPoolItem *pVoid = new SfxVoidItem( nId );
    1105           0 :         DeleteItemOnIdle( pVoid );
    1106           0 :         pRet = pVoid;
    1107             :     }
    1108             : 
    1109           0 :     return pRet;
    1110             : }
    1111             : 
    1112          52 : void SfxBindings::Execute_Impl( SfxRequest& aReq, const SfxSlot* pSlot, SfxShell* pShell )
    1113             : {
    1114          52 :     SfxItemPool &rPool = pShell->GetPool();
    1115             : 
    1116          52 :     if ( SFX_KIND_ENUM == pSlot->GetKind() )
    1117             :     {
    1118             :         // for Enum-Slots, the Master has to be excecuted with the value
    1119             :         // of the enums
    1120           0 :         const SfxSlot *pRealSlot = pShell->GetInterface()->GetRealSlot(pSlot);
    1121           0 :         const sal_uInt16 nSlotId = pRealSlot->GetSlotId();
    1122           0 :         aReq.SetSlot( nSlotId );
    1123           0 :         aReq.AppendItem( SfxAllEnumItem( rPool.GetWhich(nSlotId), pSlot->GetValue() ) );
    1124           0 :         pDispatcher->_Execute( *pShell, *pRealSlot, aReq, aReq.GetCallMode() | SfxCallMode::RECORD );
    1125             :     }
    1126          52 :     else if ( SFX_KIND_ATTR == pSlot->GetKind() )
    1127             :     {
    1128             :         // Which value has to be mapped for Attribute slots
    1129          52 :         const sal_uInt16 nSlotId = pSlot->GetSlotId();
    1130          52 :         aReq.SetSlot( nSlotId );
    1131          52 :         if ( pSlot->IsMode(SFX_SLOT_TOGGLE) )
    1132             :         {
    1133             :             // The value is attached to a toggleable attribute (Bools)
    1134          20 :             sal_uInt16 nWhich = pSlot->GetWhich(rPool);
    1135          20 :             SfxItemSet aSet(rPool, nWhich, nWhich);
    1136          20 :             SfxStateFunc aFunc  = pSlot->GetStateFnc();
    1137          20 :             pShell->CallState( aFunc, aSet );
    1138             :             const SfxPoolItem *pOldItem;
    1139          20 :             SfxItemState eState = aSet.GetItemState(nWhich, true, &pOldItem);
    1140          20 :             if ( eState == SfxItemState::DISABLED )
    1141          52 :                 return;
    1142             : 
    1143          20 :             if ( SfxItemState::DEFAULT == eState && SfxItemPool::IsWhich(nWhich) )
    1144           0 :                 pOldItem = &aSet.Get(nWhich);
    1145             : 
    1146          40 :             if ( SfxItemState::SET == eState ||
    1147           0 :                  ( SfxItemState::DEFAULT == eState &&
    1148           0 :                    SfxItemPool::IsWhich(nWhich) &&
    1149             :                    pOldItem ) )
    1150             :             {
    1151          20 :                 if ( pOldItem->ISA(SfxBoolItem) )
    1152             :                 {
    1153             :                     // we can toggle Bools
    1154          20 :                     bool bOldValue = static_cast<const SfxBoolItem *>(pOldItem)->GetValue();
    1155          20 :                     SfxBoolItem *pNewItem = static_cast<SfxBoolItem*>(pOldItem->Clone());
    1156          20 :                     pNewItem->SetValue( !bOldValue );
    1157          20 :                     aReq.AppendItem( *pNewItem );
    1158          20 :                     delete pNewItem;
    1159             :                 }
    1160           0 :                 else if ( pOldItem->ISA(SfxEnumItemInterface) &&
    1161           0 :                         static_cast<const SfxEnumItemInterface *>(pOldItem)->HasBoolValue())
    1162             :                 {
    1163             :                     // and Enums with Bool-Interface
    1164             :                     SfxEnumItemInterface *pNewItem =
    1165           0 :                         static_cast<SfxEnumItemInterface*>(pOldItem->Clone());
    1166           0 :                     pNewItem->SetBoolValue(!static_cast<const SfxEnumItemInterface *>(pOldItem)->GetBoolValue());
    1167           0 :                     aReq.AppendItem( *pNewItem );
    1168           0 :                     delete pNewItem;
    1169             :                 }
    1170             :                 else {
    1171             :                     OSL_FAIL( "Toggle only for Enums and Bools allowed" );
    1172             :                 }
    1173             :             }
    1174           0 :             else if ( SfxItemState::DONTCARE == eState )
    1175             :             {
    1176             :                 // Create one Status-Item for each Factory
    1177           0 :                 SfxPoolItem *pNewItem = pSlot->GetType()->CreateItem();
    1178             :                 DBG_ASSERT( pNewItem, "Toggle to slot without ItemFactory" );
    1179           0 :                 pNewItem->SetWhich( nWhich );
    1180             : 
    1181           0 :                 if ( pNewItem->ISA(SfxBoolItem) )
    1182             :                 {
    1183             :                   // we can toggle Bools
    1184           0 :                     static_cast<SfxBoolItem*>(pNewItem)->SetValue( true );
    1185           0 :                     aReq.AppendItem( *pNewItem );
    1186             :                 }
    1187           0 :                 else if ( pNewItem->ISA(SfxEnumItemInterface) &&
    1188           0 :                         static_cast<SfxEnumItemInterface *>(pNewItem)->HasBoolValue())
    1189             :                 {
    1190             :                     // and Enums with Bool-Interface
    1191           0 :                     static_cast<SfxEnumItemInterface*>(pNewItem)->SetBoolValue(true);
    1192           0 :                     aReq.AppendItem( *pNewItem );
    1193             :                 }
    1194             :                 else {
    1195             :                     OSL_FAIL( "Toggle only for Enums and Bools allowed" );
    1196             :                 }
    1197           0 :                 delete pNewItem;
    1198             :             }
    1199             :             else {
    1200             :                 OSL_FAIL( "suspicious Toggle-Slot" );
    1201          20 :             }
    1202             :         }
    1203             : 
    1204          52 :         pDispatcher->_Execute( *pShell, *pSlot, aReq, aReq.GetCallMode() | SfxCallMode::RECORD );
    1205             :     }
    1206             :     else
    1207           0 :         pDispatcher->_Execute( *pShell, *pSlot, aReq, aReq.GetCallMode() | SfxCallMode::RECORD );
    1208             : }
    1209             : 
    1210             : 
    1211             : 
    1212        1612 : void SfxBindings::UpdateSlotServer_Impl()
    1213             : {
    1214             :     DBG_ASSERT( pImp->pCaches != 0, "SfxBindings not initialized" );
    1215             : 
    1216             :     // synchronize
    1217        1612 :     pDispatcher->Flush();
    1218             : 
    1219        1612 :     if ( pImp->bAllMsgDirty )
    1220             :     {
    1221        1239 :         if ( !nRegLevel )
    1222             :         {
    1223             :             ::com::sun::star::uno::Reference < ::com::sun::star::frame::XFrame > xFrame
    1224        1239 :                 ( pDispatcher->GetFrame()->GetFrame().GetFrameInterface(), UNO_QUERY );
    1225        1239 :             pImp->bContextChanged = false;
    1226             :         }
    1227             :         else
    1228           0 :             pImp->bContextChanged = true;
    1229             :     }
    1230             : 
    1231      136833 :     for (size_t i = 0, nCount = pImp->pCaches->size(); i < nCount; ++i)
    1232             :     {
    1233      135221 :         SfxStateCache *pCache = (*pImp->pCaches)[i];
    1234             :         //GetSlotServer can modify pImp->pCaches
    1235      135221 :         pCache->GetSlotServer(*pDispatcher, pImp->xProv);
    1236             :     }
    1237        1612 :     pImp->bMsgDirty = pImp->bAllMsgDirty = false;
    1238             : 
    1239        1612 :     Broadcast( SfxSimpleHint(SFX_HINT_DOCCHANGED) );
    1240        1612 : }
    1241             : 
    1242             : 
    1243             : 
    1244       12771 : SfxItemSet* SfxBindings::CreateSet_Impl
    1245             : (
    1246             :     SfxStateCache*&         pCache,     // in: Status-Cache from nId
    1247             :     const SfxSlot*&         pRealSlot,  // out: RealSlot to nId
    1248             :     const SfxSlotServer**   pMsgServer, // out: Slot-Server to nId
    1249             :     SfxFoundCacheArr_Impl&  rFound      // out: List of Caches for Siblings
    1250             : )
    1251             : {
    1252             :     DBG_ASSERT( pImp->pCaches != 0, "SfxBindings not initialized" );
    1253             : 
    1254             :     DBG_ASSERT( !pImp->bMsgDirty, "CreateSet_Impl with dirty MessageServer" );
    1255             : 
    1256       12771 :     const SfxSlotServer* pMsgSvr = pCache->GetSlotServer(*pDispatcher, pImp->xProv);
    1257       12771 :     if(!pMsgSvr || !pDispatcher)
    1258        1343 :         return 0;
    1259             : 
    1260       11428 :     pRealSlot = 0;
    1261       11428 :     *pMsgServer = pMsgSvr;
    1262             : 
    1263       11428 :     sal_uInt16 nShellLevel = pMsgSvr->GetShellLevel();
    1264       11428 :     SfxShell *pShell = pDispatcher->GetShell( nShellLevel );
    1265       11428 :     if ( !pShell ) // rare GPF when browsing through update from Inet-Notify
    1266           0 :         return 0;
    1267             : 
    1268       11428 :     SfxItemPool &rPool = pShell->GetPool();
    1269             : 
    1270             :     // get the status method, which is served by the pCache
    1271       11428 :     SfxStateFunc pFnc = 0;
    1272       11428 :     const SfxInterface *pInterface = pShell->GetInterface();
    1273       11428 :     if ( SFX_KIND_ENUM == pMsgSvr->GetSlot()->GetKind() )
    1274             :     {
    1275           0 :         pRealSlot = pInterface->GetRealSlot(pMsgSvr->GetSlot());
    1276           0 :         pCache = GetStateCache( pRealSlot->GetSlotId() );
    1277             :     }
    1278             :     else
    1279       11428 :         pRealSlot = pMsgSvr->GetSlot();
    1280             : 
    1281             :     // Note: pCache can be NULL!
    1282             : 
    1283       11428 :     pFnc = pRealSlot->GetStateFnc();
    1284             : 
    1285             :     // the RealSlot is always on
    1286             :     SfxFoundCache_Impl *pFound = new SfxFoundCache_Impl(
    1287       11428 :         pRealSlot->GetSlotId(), pRealSlot->GetWhich(rPool), pRealSlot, pCache );
    1288       11428 :     rFound.push_back( pFound );
    1289             : 
    1290             :     // Search through the bindings for slots served by the same function. This ,    // will only affect slots which are present in the found interface.
    1291             : 
    1292             :     // The position of the  Statecaches in StateCache-Array
    1293       11428 :     sal_uInt16 nCachePos = pImp->nMsgPos;
    1294       11428 :     const SfxSlot *pSibling = pRealSlot->GetNextSlot();
    1295             : 
    1296             :     // the Slots ODF a interfaces ar linked in a circle
    1297      215145 :     while ( pSibling > pRealSlot )
    1298             :     {
    1299      192289 :         SfxStateFunc pSiblingFnc=0;
    1300             :         SfxStateCache *pSiblingCache =
    1301      192289 :                 GetStateCache( pSibling->GetSlotId(), &nCachePos );
    1302             : 
    1303             :         // Is the slot cached ?
    1304      192289 :         if ( pSiblingCache )
    1305             :         {
    1306       28675 :             const SfxSlotServer *pServ = pSiblingCache->GetSlotServer(*pDispatcher, pImp->xProv);
    1307       28675 :             if ( pServ && pServ->GetShellLevel() == nShellLevel )
    1308       27263 :                 pSiblingFnc = pServ->GetSlot()->GetStateFnc();
    1309             :         }
    1310             : 
    1311             :         // Does the slot have to be updated at all?
    1312      192289 :         bool bInsert = pSiblingCache && pSiblingCache->IsControllerDirty();
    1313             : 
    1314             :         // It is not enough to ask for the same shell!!
    1315      192289 :         bool bSameMethod = pSiblingCache && pFnc == pSiblingFnc;
    1316             : 
    1317             :         // If the slot is a non-dirty master slot, then maybe one of his slaves
    1318             :         // is dirty? Then the master slot is still inserted.
    1319      192289 :         if ( !bInsert && bSameMethod && pSibling->GetLinkedSlot() )
    1320             :         {
    1321             :             // Also check slave slots for Binding
    1322           0 :             const SfxSlot* pFirstSlave = pSibling->GetLinkedSlot();
    1323           0 :             for ( const SfxSlot *pSlaveSlot = pFirstSlave;
    1324           0 :                   !bInsert;
    1325             :                   pSlaveSlot = pSlaveSlot->GetNextSlot())
    1326             :             {
    1327             :                 // the slaves points to its master
    1328             :                 DBG_ASSERT(pSlaveSlot->GetLinkedSlot() == pSibling,
    1329             :                     "Wrong Master/Slave relationship!");
    1330             : 
    1331           0 :                 sal_uInt16 nCurMsgPos = pImp->nMsgPos;
    1332             :                 const SfxStateCache *pSlaveCache =
    1333           0 :                     GetStateCache( pSlaveSlot->GetSlotId(), &nCurMsgPos );
    1334             : 
    1335             :                 // Is the slave slot chached and dirty ?
    1336           0 :                 bInsert = pSlaveCache && pSlaveCache->IsControllerDirty();
    1337             : 
    1338             :                 // Slaves are chained together in a circle
    1339           0 :                 if (pSlaveSlot->GetNextSlot() == pFirstSlave)
    1340           0 :                     break;
    1341             :             }
    1342             :         }
    1343             : 
    1344      192289 :         if ( bInsert && bSameMethod )
    1345             :         {
    1346             :             SfxFoundCache_Impl *pFoundCache = new SfxFoundCache_Impl(
    1347       50744 :                 pSibling->GetSlotId(), pSibling->GetWhich(rPool),
    1348       50744 :                 pSibling, pSiblingCache );
    1349             : 
    1350       25372 :             rFound.push_back( pFoundCache );
    1351             :         }
    1352             : 
    1353      192289 :         pSibling = pSibling->GetNextSlot();
    1354             :     }
    1355             : 
    1356             :     // Create a Set from the ranges
    1357       11428 :     boost::scoped_array<sal_uInt16> pRanges(new sal_uInt16[rFound.size() * 2 + 1]);
    1358       11428 :     int j = 0;
    1359       11428 :     sal_uInt16 i = 0;
    1360       50693 :     while ( i < rFound.size() )
    1361             :     {
    1362       27837 :         pRanges[j++] = rFound[i].nWhichId;
    1363             :             // consecutive numbers
    1364       36800 :         for ( ; i < rFound.size()-1; ++i )
    1365       25372 :             if ( rFound[i].nWhichId+1 != rFound[i+1].nWhichId )
    1366       16409 :                 break;
    1367       27837 :         pRanges[j++] = rFound[i++].nWhichId;
    1368             :     }
    1369       11428 :     pRanges[j] = 0; // terminating NULL
    1370       11428 :     SfxItemSet *pSet = new SfxItemSet(rPool, pRanges.get());
    1371       11428 :     pRanges.reset();
    1372       11428 :     return pSet;
    1373             : }
    1374             : 
    1375             : 
    1376             : 
    1377       38143 : void SfxBindings::UpdateControllers_Impl
    1378             : (
    1379             :     const SfxInterface*         pIF,    // Id of the current serving Interface
    1380             :     const SfxFoundCache_Impl&   rFound, // Cache, Slot, Which etc.
    1381             :     const SfxPoolItem*          pItem,  // item to send to controller
    1382             :     SfxItemState                eState  // state of item
    1383             : )
    1384             : {
    1385             :     DBG_ASSERT( !rFound.pSlot || SFX_KIND_ENUM != rFound.pSlot->GetKind(),
    1386             :                 "direct update of enum slot isn't allowed" );
    1387             : 
    1388       38143 :     SfxStateCache* pCache = rFound.pCache;
    1389       38143 :     const SfxSlot* pSlot = rFound.pSlot;
    1390             :     DBG_ASSERT( !pCache || !pSlot || pCache->GetId() == pSlot->GetSlotId(), "SID mismatch" );
    1391             : 
    1392             :     // bound until now, the Controller to update the Slot.
    1393       38143 :     if ( pCache && pCache->IsControllerDirty() )
    1394             :     {
    1395       38143 :         if ( SfxItemState::DONTCARE == eState )
    1396             :         {
    1397             :             // ambiguous
    1398          10 :             pCache->SetState( SfxItemState::DONTCARE, reinterpret_cast<SfxPoolItem *>(-1) );
    1399             :         }
    1400       48934 :         else if ( SfxItemState::DEFAULT == eState &&
    1401       10801 :                     rFound.nWhichId > SFX_WHICH_MAX )
    1402             :         {
    1403             :             // no Status or Default but without Pool
    1404        9603 :             SfxVoidItem aVoid(0);
    1405        9603 :             pCache->SetState( SfxItemState::UNKNOWN, &aVoid );
    1406             :         }
    1407       28530 :         else if ( SfxItemState::DISABLED == eState )
    1408        4883 :             pCache->SetState(SfxItemState::DISABLED, 0);
    1409             :         else
    1410       23647 :             pCache->SetState(SfxItemState::DEFAULT, pItem);
    1411             :     }
    1412             : 
    1413             :     // Update the slots for so far available and bound Controllers for
    1414             :     // Slave-Slots (Enum-value)
    1415             :     DBG_ASSERT( !pSlot || 0 == pSlot->GetLinkedSlot() || !pItem ||
    1416             :                 pItem->ISA(SfxEnumItemInterface),
    1417             :                 "master slot with non-enum-type found" );
    1418       38143 :     const SfxSlot *pFirstSlave = pSlot ? pSlot->GetLinkedSlot() : 0;
    1419       38143 :     if ( pIF && pFirstSlave)
    1420             :     {
    1421             :         // Items cast on EnumItem
    1422             :         const SfxEnumItemInterface *pEnumItem =
    1423         196 :                 PTR_CAST(SfxEnumItemInterface,pItem);
    1424         196 :         if ( eState == SfxItemState::DEFAULT && !pEnumItem )
    1425           0 :             eState = SfxItemState::DONTCARE;
    1426             :         else
    1427         196 :             eState = SfxControllerItem::GetItemState( pEnumItem );
    1428             : 
    1429             :         // Iterate over all Slaves-Slots
    1430        2940 :         for ( const SfxSlot *pSlave = pFirstSlave; pSlave; pSlave = pSlave->GetNextSlot() )
    1431             :         {
    1432             :             DBG_ASSERT(pSlave, "Wrong SlaveSlot binding!");
    1433             :             DBG_ASSERT(SFX_KIND_ENUM == pSlave->GetKind(),"non enum slaves aren't allowed");
    1434             :             DBG_ASSERT(pSlave->GetMasterSlotId() == pSlot->GetSlotId(),"Wrong MasterSlot!");
    1435             : 
    1436             :             // Binding exist for function ?
    1437        2940 :             SfxStateCache *pEnumCache = GetStateCache( pSlave->GetSlotId() );
    1438        2940 :             if ( pEnumCache )
    1439             :             {
    1440           0 :                 pEnumCache->Invalidate(false);
    1441             : 
    1442             :                 // HACK(CONTROL/SELECT Kram) ???
    1443           0 :                 if ( eState == SfxItemState::DONTCARE && rFound.nWhichId == 10144 )
    1444             :                 {
    1445           0 :                     SfxVoidItem aVoid(0);
    1446           0 :                     pEnumCache->SetState( SfxItemState::UNKNOWN, &aVoid );
    1447             : 
    1448           0 :                     if (pSlave->GetNextSlot() == pFirstSlave)
    1449           0 :                         break;
    1450             : 
    1451           0 :                     continue;
    1452             :                 }
    1453             : 
    1454           0 :                 if ( SfxItemState::DISABLED == eState || (pEnumItem && !pEnumItem->IsEnabled( pSlave->GetSlotId())) )
    1455             :                 {
    1456             :                     // disabled
    1457           0 :                     pEnumCache->SetState(SfxItemState::DISABLED, 0);
    1458             :                 }
    1459           0 :                 else if ( SfxItemState::DEFAULT == eState && pEnumItem )
    1460             :                 {
    1461             :                     // Determine enum value
    1462           0 :                     sal_uInt16 nValue = pEnumItem->GetEnumValue();
    1463           0 :                     SfxBoolItem aBool( rFound.nWhichId, pSlave->GetValue() == nValue );
    1464           0 :                     pEnumCache->SetState(SfxItemState::DEFAULT, &aBool);
    1465             :                 }
    1466             :                 else
    1467             :                 {
    1468             :                     // ambiguous
    1469           0 :                     pEnumCache->SetState( SfxItemState::DONTCARE, reinterpret_cast<SfxPoolItem *>(-1) );
    1470             :                 }
    1471             :             }
    1472             : 
    1473        2940 :             if (pSlave->GetNextSlot() == pFirstSlave)
    1474         196 :                 break;
    1475             :         }
    1476             :     }
    1477       38143 : }
    1478             : 
    1479             : 
    1480             : 
    1481             : 
    1482        3128 : IMPL_LINK( SfxBindings, NextJob_Impl, Timer *, pTimer )
    1483             : {
    1484             : #ifdef DBG_UTIL
    1485             :     // on Windows very often C++ Exceptions (GPF etc.) are caught by MSVCRT
    1486             :     // or another MS library try to get them here
    1487             :     try
    1488             :     {
    1489             : #endif
    1490        1564 :     const unsigned MAX_INPUT_DELAY = 200;
    1491             : 
    1492             :     DBG_ASSERT( pImp->pCaches != 0, "SfxBindings not initialized" );
    1493             : 
    1494        1564 :     if ( Application::GetLastInputInterval() < MAX_INPUT_DELAY && pTimer )
    1495             :     {
    1496           0 :         pImp->aTimer.SetTimeout(TIMEOUT_UPDATING);
    1497           0 :         return sal_True;
    1498             :     }
    1499             : 
    1500        1564 :     SfxApplication *pSfxApp = SfxGetpApp();
    1501             : 
    1502        1564 :     if( pDispatcher )
    1503        1564 :         pDispatcher->Update_Impl();
    1504             : 
    1505             :     // modifying the SfxObjectInterface-stack without SfxBindings => nothing to do
    1506        1564 :     SfxViewFrame* pFrame = pDispatcher ? pDispatcher->GetFrame() : NULL;
    1507        1564 :     if ( (pFrame && !pFrame->GetObjectShell()->AcceptStateUpdate()) || pSfxApp->IsDowning() || pImp->pCaches->empty() )
    1508             :     {
    1509           0 :         return sal_True;
    1510             :     }
    1511        1564 :     if ( !pDispatcher || !pDispatcher->IsFlushed() )
    1512             :     {
    1513           0 :         return sal_True;
    1514             :     }
    1515             : 
    1516             :     // if possible Update all server / happens in its own time slice
    1517        1564 :     if ( pImp->bMsgDirty )
    1518             :     {
    1519         403 :         UpdateSlotServer_Impl();
    1520         403 :         return sal_False;
    1521             :     }
    1522             : 
    1523        1161 :     pImp->bAllDirty = false;
    1524        1161 :     pImp->aTimer.SetTimeout(TIMEOUT_UPDATING);
    1525             : 
    1526             :     // at least 10 loops and further if more jobs are available but no input
    1527        1161 :     bool bPreEmptive = pTimer && !pSfxApp->Get_Impl()->nInReschedule;
    1528        1161 :     sal_uInt16 nLoops = 10;
    1529        1161 :     pImp->bInNextJob = true;
    1530        1161 :     const sal_uInt16 nCount = pImp->pCaches->size();
    1531        2571 :     while ( pImp->nMsgPos < nCount )
    1532             :     {
    1533             :         // iterate through the bound functions
    1534        1161 :         bool bJobDone = false;
    1535       35303 :         while ( !bJobDone )
    1536             :         {
    1537       33893 :             SfxStateCache* pCache = (*pImp->pCaches)[pImp->nMsgPos];
    1538             :             DBG_ASSERT( pCache, "invalid SfxStateCache-position in job queue" );
    1539       33893 :             bool bWasDirty = pCache->IsControllerDirty();
    1540       33893 :             if ( bWasDirty )
    1541             :             {
    1542       10299 :                     Update_Impl( pCache );
    1543             :                     DBG_ASSERT( nCount == pImp->pCaches->size(),
    1544             :                             "Reschedule in StateChanged => buff" );
    1545             :             }
    1546             : 
    1547             :             // skip to next function binding
    1548       33893 :             ++pImp->nMsgPos;
    1549             : 
    1550             :             // keep job if it is not completed, but any input is available
    1551       33893 :             bJobDone = pImp->nMsgPos >= nCount;
    1552       33893 :             if ( bJobDone && pImp->bFirstRound )
    1553             :             {
    1554             : 
    1555             :                 // Update of the  preferred shell has been done, now may
    1556             :                 // also the others shells be updated
    1557           2 :                 bJobDone = false;
    1558           2 :                 pImp->bFirstRound = false;
    1559           2 :                 pImp->nMsgPos = 0;
    1560             :             }
    1561             : 
    1562       33893 :             if ( bWasDirty && !bJobDone && bPreEmptive && (--nLoops == 0) )
    1563             :             {
    1564         912 :                 pImp->bInNextJob = false;
    1565         912 :                 return sal_False;
    1566             :             }
    1567             :         }
    1568             :     }
    1569             : 
    1570         249 :     pImp->nMsgPos = 0;
    1571             : 
    1572             :     // check for volatile slots
    1573         249 :     bool bVolatileSlotsPresent = false;
    1574       28937 :     for ( sal_uInt16 n = 0; n < nCount; ++n )
    1575             :     {
    1576       28688 :         SfxStateCache* pCache = (*pImp->pCaches)[n];
    1577       28688 :         const SfxSlotServer *pSlotServer = pCache->GetSlotServer(*pDispatcher, pImp->xProv);
    1578       28688 :         if ( pSlotServer && pSlotServer->GetSlot()->IsMode(SFX_SLOT_VOLATILE) )
    1579             :         {
    1580           0 :             pCache->Invalidate(false);
    1581           0 :             bVolatileSlotsPresent = true;
    1582             :         }
    1583             :     }
    1584             : 
    1585         249 :     if (bVolatileSlotsPresent)
    1586           0 :         pImp->aTimer.SetTimeout(TIMEOUT_IDLE);
    1587             :     else
    1588         249 :         pImp->aTimer.Stop();
    1589             : 
    1590             :     // Update round is finished
    1591         249 :     pImp->bInNextJob = false;
    1592         249 :     Broadcast(SfxSimpleHint(SFX_HINT_UPDATEDONE));
    1593         249 :     return sal_True;
    1594             : #ifdef DBG_UTIL
    1595             :     }
    1596             :     catch (...)
    1597             :     {
    1598             :         OSL_FAIL("C++ exception caught!");
    1599             :         pImp->bInNextJob = false;
    1600             :     }
    1601             : 
    1602             :     return sal_False;
    1603             : #endif
    1604             : }
    1605             : 
    1606             : 
    1607             : 
    1608      601019 : sal_uInt16 SfxBindings::EnterRegistrations(const char *pFile, int nLine)
    1609             : {
    1610             :     SAL_INFO(
    1611             :         "sfx.control",
    1612             :         std::setw(std::min(nRegLevel, sal_uInt16(8))) << ' ' << "this = " << this
    1613             :             << " Level = " << nRegLevel << " SfxBindings::EnterRegistrations "
    1614             :             << (pFile
    1615             :                 ? SAL_STREAM("File: " << pFile << " Line: " << nLine) : ""));
    1616             : 
    1617             :     // When bindings are locked, also lock sub bindings.
    1618      601019 :     if ( pImp->pSubBindings )
    1619             :     {
    1620           0 :         pImp->pSubBindings->ENTERREGISTRATIONS();
    1621             : 
    1622             :         // These EnterRegistrations are not "real" for the SubBindings
    1623           0 :         pImp->pSubBindings->pImp->nOwnRegLevel--;
    1624             : 
    1625             :         // Synchronize Bindings
    1626           0 :         pImp->pSubBindings->nRegLevel = nRegLevel + pImp->pSubBindings->pImp->nOwnRegLevel + 1;
    1627             :     }
    1628             : 
    1629      601019 :     pImp->nOwnRegLevel++;
    1630             : 
    1631             :     // check if this is the outer most level
    1632      601019 :     if ( ++nRegLevel == 1 )
    1633             :     {
    1634             :         // stop background-processing
    1635      151518 :         pImp->aTimer.Stop();
    1636             : 
    1637             :         // flush the cache
    1638      151518 :         pImp->nCachedFunc1 = 0;
    1639      151518 :         pImp->nCachedFunc2 = 0;
    1640             : 
    1641             :         // Mark if the all of the Caches have dissapered.
    1642      151518 :         pImp->bCtrlReleased = false;
    1643             :     }
    1644             : 
    1645      601019 :     return nRegLevel;
    1646             : }
    1647             : 
    1648             : 
    1649      590001 : void SfxBindings::LeaveRegistrations( sal_uInt16 nLevel, const char *pFile, int nLine )
    1650             : {
    1651             :     (void)nLevel; // unused variable
    1652             :     DBG_ASSERT( nRegLevel, "Leave without Enter" );
    1653             :     DBG_ASSERT( nLevel == USHRT_MAX || nLevel == nRegLevel, "wrong Leave" );
    1654             : 
    1655             :     // Only when the SubBindings are still locked by the Superbindings,
    1656             :     // remove this lock (i.e. if there are more locks than "real" ones)
    1657      590001 :     if ( pImp->pSubBindings && pImp->pSubBindings->nRegLevel > pImp->pSubBindings->pImp->nOwnRegLevel )
    1658             :     {
    1659             :         // Synchronize Bindings
    1660           0 :         pImp->pSubBindings->nRegLevel = nRegLevel + pImp->pSubBindings->pImp->nOwnRegLevel;
    1661             : 
    1662             :         // This LeaveRegistrations is not "real" for SubBindings
    1663           0 :         pImp->pSubBindings->pImp->nOwnRegLevel++;
    1664           0 :         pImp->pSubBindings->LEAVEREGISTRATIONS();
    1665             :     }
    1666             : 
    1667      590001 :     pImp->nOwnRegLevel--;
    1668             : 
    1669             :     // check if this is the outer most level
    1670      590001 :     if ( --nRegLevel == 0 && !SfxGetpApp()->IsDowning() )
    1671             :     {
    1672      151520 :         if ( pImp->bContextChanged )
    1673             :         {
    1674           0 :             pImp->bContextChanged = false;
    1675             :         }
    1676             : 
    1677      151520 :         SfxViewFrame* pFrame = pDispatcher->GetFrame();
    1678             : 
    1679             :         // If possible remove unused Caches, for example prepare PlugInInfo
    1680      151520 :         if ( pImp->bCtrlReleased )
    1681             :         {
    1682       97272 :             for ( sal_uInt16 nCache = pImp->pCaches->size(); nCache > 0; --nCache )
    1683             :             {
    1684             :                 // Get Cache via ::com::sun::star::sdbcx::Index
    1685       91922 :                 SfxStateCache *pCache = (*pImp->pCaches)[nCache-1];
    1686             : 
    1687             :                 // No interested Controller present
    1688       91922 :                 if ( pCache->GetItemLink() == 0 && !pCache->GetInternalController() )
    1689             :                 {
    1690             :                     // Remove Cache. Safety: first remove and then delete
    1691       73122 :                     pImp->pCaches->erase(pImp->pCaches->begin() + nCache - 1);
    1692       73122 :                     delete pCache;
    1693             :                 }
    1694             :             }
    1695             :         }
    1696             : 
    1697             :         // restart background-processing
    1698      151520 :         pImp->nMsgPos = 0;
    1699      151520 :         if ( !pFrame || !pFrame->GetObjectShell() )
    1700      595509 :             return;
    1701      146012 :         if ( pImp->pCaches && !pImp->pCaches->empty() )
    1702             :         {
    1703      129330 :             pImp->aTimer.Stop();
    1704      129330 :             pImp->aTimer.SetTimeout(TIMEOUT_FIRST);
    1705      129330 :             pImp->aTimer.Start();
    1706             :         }
    1707             :     }
    1708             : 
    1709             :     SAL_INFO(
    1710             :         "sfx.control",
    1711             :         std::setw(std::min(nRegLevel, sal_uInt16(8))) << ' ' << "this = " << this
    1712             :             << " Level = " << nRegLevel << " SfxBindings::LeaveRegistrations "
    1713             :             << (pFile
    1714             :                 ? SAL_STREAM("File: " << pFile << " Line: " << nLine) : ""));
    1715             : }
    1716             : 
    1717             : 
    1718             : 
    1719       16468 : void SfxBindings::SetDispatcher( SfxDispatcher *pDisp )
    1720             : {
    1721       16468 :     SfxDispatcher *pOldDispat = pDispatcher;
    1722       16468 :     if ( pDisp != pDispatcher )
    1723             :     {
    1724       11030 :         if ( pOldDispat )
    1725             :         {
    1726        5514 :             SfxBindings* pBind = pOldDispat->GetBindings();
    1727       16542 :             while ( pBind )
    1728             :             {
    1729        5514 :                 if ( pBind->pImp->pSubBindings == this && pBind->pDispatcher != pDisp )
    1730           8 :                     pBind->SetSubBindings_Impl( NULL );
    1731        5514 :                 pBind = pBind->pImp->pSubBindings;
    1732             :             }
    1733             :         }
    1734             : 
    1735       11030 :         pDispatcher = pDisp;
    1736             : 
    1737       11030 :         ::com::sun::star::uno::Reference < ::com::sun::star::frame::XDispatchProvider > xProv;
    1738       11030 :         if ( pDisp )
    1739       11032 :             xProv = ::com::sun::star::uno::Reference < ::com::sun::star::frame::XDispatchProvider >
    1740       11032 :                                         ( pDisp->GetFrame()->GetFrame().GetFrameInterface(), UNO_QUERY );
    1741             : 
    1742       11030 :         SetDispatchProvider_Impl( xProv );
    1743       11030 :         InvalidateAll( true );
    1744       11030 :         InvalidateUnoControllers_Impl();
    1745             : 
    1746       11030 :         if ( pDispatcher && !pOldDispat )
    1747             :         {
    1748        5516 :             if ( pImp->pSubBindings && pImp->pSubBindings->pDispatcher != pOldDispat )
    1749             :             {
    1750             :                 OSL_FAIL( "SubBindings already set before activating!" );
    1751           0 :                 pImp->pSubBindings->ENTERREGISTRATIONS();
    1752             :             }
    1753        5516 :             LEAVEREGISTRATIONS();
    1754             :         }
    1755        5514 :         else if( !pDispatcher )
    1756             :         {
    1757        5514 :             ENTERREGISTRATIONS();
    1758        5514 :             if ( pImp->pSubBindings && pImp->pSubBindings->pDispatcher != pOldDispat )
    1759             :             {
    1760             :                 OSL_FAIL( "SubBindings still set even when deactivating!" );
    1761           0 :                 pImp->pSubBindings->LEAVEREGISTRATIONS();
    1762             :             }
    1763             :         }
    1764             : 
    1765       11030 :         Broadcast( SfxSimpleHint( SFX_HINT_DATACHANGED ) );
    1766             : 
    1767       11030 :         if ( pDisp )
    1768             :         {
    1769        5516 :             SfxBindings* pBind = pDisp->GetBindings();
    1770       11032 :             while ( pBind && pBind != this )
    1771             :             {
    1772           8 :                 if ( !pBind->pImp->pSubBindings )
    1773             :                 {
    1774           8 :                     pBind->SetSubBindings_Impl( this );
    1775           8 :                     break;
    1776             :                 }
    1777             : 
    1778           0 :                 pBind = pBind->pImp->pSubBindings;
    1779             :             }
    1780       11030 :         }
    1781             :     }
    1782       16468 : }
    1783             : 
    1784             : 
    1785             : 
    1786           0 : void SfxBindings::ClearCache_Impl( sal_uInt16 nSlotId )
    1787             : {
    1788           0 :     SfxStateCache* pCache = GetStateCache(nSlotId);
    1789           0 :     if (!pCache)
    1790           0 :         return;
    1791           0 :     pCache->ClearCache();
    1792             : }
    1793             : 
    1794             : 
    1795           0 : void SfxBindings::StartUpdate_Impl( bool bComplete )
    1796             : {
    1797           0 :     if ( pImp->pSubBindings )
    1798           0 :         pImp->pSubBindings->StartUpdate_Impl( bComplete );
    1799             : 
    1800           0 :     if ( !bComplete )
    1801             :         // Update may be interrupted
    1802           0 :         NextJob_Impl(&pImp->aTimer);
    1803             :     else
    1804             :         // Update all slots in a row
    1805           0 :         NextJob_Impl(0);
    1806           0 : }
    1807             : 
    1808             : 
    1809             : 
    1810        8246 : SfxItemState SfxBindings::QueryState( sal_uInt16 nSlot, SfxPoolItem* &rpState )
    1811             : {
    1812        8246 :     ::com::sun::star::uno::Reference< ::com::sun::star::frame::XDispatch >  xDisp;
    1813        8246 :     SfxStateCache *pCache = GetStateCache( nSlot );
    1814        8246 :     if ( pCache )
    1815        7397 :         xDisp = pCache->GetDispatch();
    1816        8246 :     if ( xDisp.is() || !pCache )
    1817             :     {
    1818         849 :         const SfxSlot* pSlot = SfxSlotPool::GetSlotPool( pDispatcher->GetFrame() ).GetSlot( nSlot );
    1819         849 :         if ( !pSlot || !pSlot->pUnoName )
    1820           0 :             return SfxItemState::DISABLED;
    1821             : 
    1822         849 :         ::com::sun::star::util::URL aURL;
    1823        1698 :         OUString aCmd( ".uno:" );
    1824         849 :         aURL.Protocol = aCmd;
    1825         849 :         aURL.Path = OUString::createFromAscii(pSlot->GetUnoName());
    1826         849 :         aCmd += aURL.Path;
    1827         849 :         aURL.Complete = aCmd;
    1828         849 :         aURL.Main = aCmd;
    1829             : 
    1830         849 :         if ( !xDisp.is() )
    1831         849 :             xDisp = pImp->xProv->queryDispatch( aURL, OUString(), 0 );
    1832             : 
    1833         849 :         if ( xDisp.is() )
    1834             :         {
    1835         849 :             ::com::sun::star::uno::Reference< ::com::sun::star::lang::XUnoTunnel > xTunnel( xDisp, ::com::sun::star::uno::UNO_QUERY );
    1836         849 :             SfxOfficeDispatch* pDisp = NULL;
    1837         849 :             if ( xTunnel.is() )
    1838             :             {
    1839         849 :                 sal_Int64 nImplementation = xTunnel->getSomething(SfxOfficeDispatch::impl_getStaticIdentifier());
    1840         849 :                 pDisp = reinterpret_cast< SfxOfficeDispatch* >( sal::static_int_cast< sal_IntPtr >( nImplementation ));
    1841             :             }
    1842             : 
    1843         849 :             if ( !pDisp )
    1844             :             {
    1845           0 :                 bool bDeleteCache = false;
    1846           0 :                 if ( !pCache )
    1847             :                 {
    1848           0 :                     pCache = new SfxStateCache( nSlot );
    1849           0 :                     pCache->GetSlotServer( *GetDispatcher_Impl(), pImp->xProv );
    1850           0 :                     bDeleteCache = true;
    1851             :                 }
    1852             : 
    1853           0 :                 SfxItemState eState = SfxItemState::SET;
    1854           0 :                 SfxPoolItem *pItem=NULL;
    1855           0 :                 BindDispatch_Impl *pBind = new BindDispatch_Impl( xDisp, aURL, pCache, pSlot );
    1856           0 :                 pBind->acquire();
    1857           0 :                 xDisp->addStatusListener( pBind, aURL );
    1858           0 :                 if ( !pBind->GetStatus().IsEnabled )
    1859             :                 {
    1860           0 :                     eState = SfxItemState::DISABLED;
    1861             :                 }
    1862             :                 else
    1863             :                 {
    1864           0 :                     ::com::sun::star::uno::Any aAny = pBind->GetStatus().State;
    1865           0 :                     ::com::sun::star::uno::Type pType = aAny.getValueType();
    1866             : 
    1867           0 :                     if ( pType == ::getBooleanCppuType() )
    1868             :                     {
    1869           0 :                         bool bTemp = false;
    1870           0 :                         aAny >>= bTemp ;
    1871           0 :                         pItem = new SfxBoolItem( nSlot, bTemp );
    1872             :                     }
    1873           0 :                     else if ( pType == ::cppu::UnoType< ::cppu::UnoUnsignedShortType >::get() )
    1874             :                     {
    1875           0 :                         sal_uInt16 nTemp = 0;
    1876           0 :                         aAny >>= nTemp ;
    1877           0 :                         pItem = new SfxUInt16Item( nSlot, nTemp );
    1878             :                     }
    1879           0 :                     else if ( pType == cppu::UnoType<sal_uInt32>::get() )
    1880             :                     {
    1881           0 :                         sal_uInt32 nTemp = 0;
    1882           0 :                         aAny >>= nTemp ;
    1883           0 :                         pItem = new SfxUInt32Item( nSlot, nTemp );
    1884             :                     }
    1885           0 :                     else if ( pType == cppu::UnoType<OUString>::get() )
    1886             :                     {
    1887           0 :                         OUString sTemp ;
    1888           0 :                         aAny >>= sTemp ;
    1889           0 :                         pItem = new SfxStringItem( nSlot, sTemp );
    1890             :                     }
    1891             :                     else
    1892           0 :                         pItem = new SfxVoidItem( nSlot );
    1893             :                 }
    1894             : 
    1895           0 :                 xDisp->removeStatusListener( pBind, aURL );
    1896           0 :                 pBind->Release();
    1897           0 :                 rpState = pItem;
    1898           0 :                 if ( bDeleteCache )
    1899           0 :                     DELETEZ( pCache );
    1900           0 :                 return eState;
    1901         849 :             }
    1902         849 :         }
    1903             :     }
    1904             : 
    1905             :     // Then test at the dispatcher to check if the returned items from
    1906             :     // there are always DELETE_ON_IDLE, a copy of it has to be made in
    1907             :     // order to allow for transition of ownership.
    1908        8246 :     const SfxPoolItem *pItem = NULL;
    1909        8246 :     SfxItemState eState = pDispatcher->QueryState( nSlot, pItem );
    1910        8246 :     if ( eState == SfxItemState::SET )
    1911             :     {
    1912             :         DBG_ASSERT( pItem, "SfxItemState::SET but no item!" );
    1913           0 :         if ( pItem )
    1914           0 :             rpState = pItem->Clone();
    1915             :     }
    1916        8246 :     else if ( eState == SfxItemState::DEFAULT && pItem )
    1917             :     {
    1918        8244 :         rpState = pItem->Clone();
    1919             :     }
    1920             : 
    1921        8246 :     return eState;
    1922             : }
    1923             : 
    1924          16 : void SfxBindings::SetSubBindings_Impl( SfxBindings *pSub )
    1925             : {
    1926          16 :     if ( pImp->pSubBindings )
    1927             :     {
    1928           8 :         pImp->pSubBindings->SetDispatchProvider_Impl( ::com::sun::star::uno::Reference< ::com::sun::star::frame::XDispatchProvider > () );
    1929           8 :         pImp->pSubBindings->pImp->pSuperBindings = NULL;
    1930             :     }
    1931             : 
    1932          16 :     pImp->pSubBindings = pSub;
    1933             : 
    1934          16 :     if ( pSub )
    1935             :     {
    1936           8 :         pImp->pSubBindings->SetDispatchProvider_Impl( pImp->xProv );
    1937           8 :         pSub->pImp->pSuperBindings = this;
    1938             :     }
    1939          16 : }
    1940             : 
    1941       16398 : SfxBindings* SfxBindings::GetSubBindings_Impl( bool bTop ) const
    1942             : {
    1943       16398 :     SfxBindings *pRet = pImp->pSubBindings;
    1944       16398 :     if ( bTop )
    1945             :     {
    1946           0 :         while ( pRet->pImp->pSubBindings )
    1947           0 :             pRet = pRet->pImp->pSubBindings;
    1948             :     }
    1949             : 
    1950       16398 :     return pRet;
    1951             : }
    1952             : 
    1953        5508 : void SfxBindings::SetWorkWindow_Impl( SfxWorkWindow* pWork )
    1954             : {
    1955        5508 :     pImp->pWorkWin = pWork;
    1956        5508 : }
    1957             : 
    1958        6683 : SfxWorkWindow* SfxBindings::GetWorkWindow_Impl() const
    1959             : {
    1960        6683 :     return pImp->pWorkWin;
    1961             : }
    1962             : 
    1963           0 : void SfxBindings::RegisterUnoController_Impl( SfxUnoControllerItem* pControl )
    1964             : {
    1965           0 :     if ( !pImp->pUnoCtrlArr )
    1966           0 :         pImp->pUnoCtrlArr = new SfxUnoControllerArr_Impl;
    1967           0 :     pImp->pUnoCtrlArr->push_back( pControl );
    1968           0 : }
    1969             : 
    1970           0 : void SfxBindings::ReleaseUnoController_Impl( SfxUnoControllerItem* pControl )
    1971             : {
    1972           0 :     if ( pImp->pUnoCtrlArr )
    1973             :     {
    1974             :         SfxUnoControllerArr_Impl::iterator it = std::find(
    1975           0 :             pImp->pUnoCtrlArr->begin(), pImp->pUnoCtrlArr->end(), pControl );
    1976           0 :         if ( it != pImp->pUnoCtrlArr->end() )
    1977             :         {
    1978           0 :             pImp->pUnoCtrlArr->erase( it );
    1979           0 :             return;
    1980             :         }
    1981             :     }
    1982             : 
    1983           0 :     if ( pImp->pSubBindings )
    1984           0 :         pImp->pSubBindings->ReleaseUnoController_Impl( pControl );
    1985             : }
    1986             : 
    1987       22060 : void SfxBindings::InvalidateUnoControllers_Impl()
    1988             : {
    1989       22060 :     if ( pImp->pUnoCtrlArr )
    1990             :     {
    1991           0 :         sal_uInt16 nCount = pImp->pUnoCtrlArr->size();
    1992           0 :         for ( sal_uInt16 n=nCount; n>0; n-- )
    1993             :         {
    1994           0 :             SfxUnoControllerItem *pCtrl = (*pImp->pUnoCtrlArr)[n-1];
    1995           0 :             ::com::sun::star::uno::Reference< ::com::sun::star::frame::XStatusListener >  xRef( (::cppu::OWeakObject*)pCtrl, ::com::sun::star::uno::UNO_QUERY );
    1996           0 :             pCtrl->ReleaseDispatch();
    1997           0 :             pCtrl->GetNewDispatch();
    1998           0 :         }
    1999             :     }
    2000             : 
    2001       22060 :     if ( pImp->pSubBindings )
    2002           0 :         pImp->pSubBindings->InvalidateUnoControllers_Impl();
    2003       22060 : }
    2004             : 
    2005       23809 : bool SfxBindings::IsInUpdate() const
    2006             : {
    2007       23809 :     bool bInUpdate = pImp->bInUpdate;
    2008       23809 :     if ( !bInUpdate && pImp->pSubBindings )
    2009           0 :         bInUpdate = pImp->pSubBindings->IsInUpdate();
    2010       23809 :     return bInUpdate;
    2011             : }
    2012             : 
    2013         620 : void SfxBindings::SetVisibleState( sal_uInt16 nId, bool bShow )
    2014             : {
    2015         620 :     ::com::sun::star::uno::Reference< ::com::sun::star::frame::XDispatch >  xDisp;
    2016         620 :     SfxStateCache *pCache = GetStateCache( nId );
    2017         620 :     if ( pCache )
    2018           0 :         pCache->SetVisibleState( bShow );
    2019         620 : }
    2020             : 
    2021       19089 : void SfxBindings::SetActiveFrame( const ::com::sun::star::uno::Reference< ::com::sun::star::frame::XFrame > & rFrame )
    2022             : {
    2023       19089 :     if ( rFrame.is() || !pDispatcher )
    2024        5438 :         SetDispatchProvider_Impl( ::com::sun::star::uno::Reference< ::com::sun::star::frame::XDispatchProvider > ( rFrame, ::com::sun::star::uno::UNO_QUERY ) );
    2025             :     else
    2026             :         SetDispatchProvider_Impl( ::com::sun::star::uno::Reference< ::com::sun::star::frame::XDispatchProvider > (
    2027       13651 :             pDispatcher->GetFrame()->GetFrame().GetFrameInterface(), ::com::sun::star::uno::UNO_QUERY ) );
    2028       19089 : }
    2029             : 
    2030       16969 : const ::com::sun::star::uno::Reference< ::com::sun::star::frame::XFrame > SfxBindings::GetActiveFrame() const
    2031             : {
    2032       16969 :     const ::com::sun::star::uno::Reference< ::com::sun::star::frame::XFrame > xFrame( pImp->xProv, ::com::sun::star::uno::UNO_QUERY );
    2033       16969 :     if ( xFrame.is() || !pDispatcher )
    2034       16761 :         return xFrame;
    2035             :     else
    2036         208 :         return pDispatcher->GetFrame()->GetFrame().GetFrameInterface();
    2037             : }
    2038             : 
    2039       30135 : void SfxBindings::SetDispatchProvider_Impl( const ::com::sun::star::uno::Reference< ::com::sun::star::frame::XDispatchProvider > & rProv )
    2040             : {
    2041       30135 :     bool bInvalidate = ( rProv != pImp->xProv );
    2042       30135 :     if ( bInvalidate )
    2043             :     {
    2044       11030 :         pImp->xProv = rProv;
    2045       11030 :         InvalidateAll( true );
    2046       11030 :         InvalidateUnoControllers_Impl();
    2047             :     }
    2048             : 
    2049       30135 :     if ( pImp->pSubBindings )
    2050           0 :         pImp->pSubBindings->SetDispatchProvider_Impl( pImp->xProv );
    2051       30135 : }
    2052             : 
    2053           0 : bool SfxBindings::ExecuteCommand_Impl( const OUString& rCommand )
    2054             : {
    2055           0 :     ::com::sun::star::util::URL aURL;
    2056           0 :     aURL.Complete = rCommand;
    2057           0 :     Reference< util::XURLTransformer > xTrans( util::URLTransformer::create( ::comphelper::getProcessComponentContext() ) );
    2058           0 :     xTrans->parseStrict( aURL );
    2059           0 :     ::com::sun::star::uno::Reference< ::com::sun::star::frame::XDispatch >  xDisp = pImp->xProv->queryDispatch( aURL, OUString(), 0 );
    2060           0 :     if ( xDisp.is() )
    2061             :     {
    2062           0 :         new SfxAsyncExec_Impl( aURL, xDisp );
    2063           0 :         return true;
    2064             :     }
    2065             : 
    2066           0 :     return false;
    2067             : }
    2068             : 
    2069           0 : com::sun::star::uno::Reference< com::sun::star::frame::XDispatchRecorder > SfxBindings::GetRecorder() const
    2070             : {
    2071           0 :     return pImp->xRecorder;
    2072             : }
    2073             : 
    2074        5506 : void SfxBindings::SetRecorder_Impl( com::sun::star::uno::Reference< com::sun::star::frame::XDispatchRecorder >& rRecorder )
    2075             : {
    2076        5506 :     pImp->xRecorder = rRecorder;
    2077        5506 : }
    2078             : 
    2079           0 : void SfxBindings::ContextChanged_Impl()
    2080             : {
    2081           0 :     if ( !pImp->bInUpdate && ( !pImp->bContextChanged || !pImp->bAllMsgDirty ) )
    2082             :     {
    2083           0 :         InvalidateAll( true );
    2084             :     }
    2085           0 : }
    2086             : 
    2087      308677 : uno::Reference < frame::XDispatch > SfxBindings::GetDispatch( const SfxSlot* pSlot, const util::URL& aURL, bool bMasterCommand )
    2088             : {
    2089      308677 :     uno::Reference < frame::XDispatch > xRet;
    2090      308677 :     SfxStateCache* pCache = GetStateCache( pSlot->nSlotId );
    2091      308677 :     if ( pCache && !bMasterCommand )
    2092      203306 :         xRet = pCache->GetInternalDispatch();
    2093      308677 :     if ( !xRet.is() )
    2094             :     {
    2095             :         // dispatches for slaves are unbound, they don't have a state
    2096             :         SfxOfficeDispatch* pDispatch = bMasterCommand ?
    2097         114 :             new SfxOfficeDispatch( pDispatcher, pSlot, aURL ) :
    2098      130455 :             new SfxOfficeDispatch( *this, pDispatcher, pSlot, aURL );
    2099             : 
    2100      130341 :         pDispatch->SetMasterUnoCommand( bMasterCommand );
    2101      130341 :         xRet = uno::Reference < frame::XDispatch >( pDispatch );
    2102      130341 :         if ( !pCache )
    2103      105257 :             pCache = GetStateCache( pSlot->nSlotId );
    2104             : 
    2105             :         DBG_ASSERT( pCache, "No cache for OfficeDispatch!" );
    2106      130341 :         if ( pCache && !bMasterCommand )
    2107      130227 :             pCache->SetInternalDispatch( xRet );
    2108             :     }
    2109             : 
    2110      308677 :     return xRet;
    2111         951 : }
    2112             : 
    2113             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10