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

Generated by: LCOV version 1.10