1d119d52dSAndrew Rist /************************************************************** 2cdf0e10cSrcweir * 3d119d52dSAndrew Rist * Licensed to the Apache Software Foundation (ASF) under one 4d119d52dSAndrew Rist * or more contributor license agreements. See the NOTICE file 5d119d52dSAndrew Rist * distributed with this work for additional information 6d119d52dSAndrew Rist * regarding copyright ownership. The ASF licenses this file 7d119d52dSAndrew Rist * to you under the Apache License, Version 2.0 (the 8d119d52dSAndrew Rist * "License"); you may not use this file except in compliance 9d119d52dSAndrew Rist * with the License. You may obtain a copy of the License at 10cdf0e10cSrcweir * 11d119d52dSAndrew Rist * http://www.apache.org/licenses/LICENSE-2.0 12cdf0e10cSrcweir * 13d119d52dSAndrew Rist * Unless required by applicable law or agreed to in writing, 14d119d52dSAndrew Rist * software distributed under the License is distributed on an 15d119d52dSAndrew Rist * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16d119d52dSAndrew Rist * KIND, either express or implied. See the License for the 17d119d52dSAndrew Rist * specific language governing permissions and limitations 18d119d52dSAndrew Rist * under the License. 19cdf0e10cSrcweir * 20d119d52dSAndrew Rist *************************************************************/ 21d119d52dSAndrew Rist 22d119d52dSAndrew Rist 23cdf0e10cSrcweir 24cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove 25cdf0e10cSrcweir #include "precompiled_sfx2.hxx" 26cdf0e10cSrcweir 27cdf0e10cSrcweir #include <hash_map> 28cdf0e10cSrcweir #include <svl/itempool.hxx> 29cdf0e10cSrcweir #include <svl/itemiter.hxx> 30cdf0e10cSrcweir #include <svl/eitem.hxx> 31cdf0e10cSrcweir #include <svl/aeitem.hxx> 32cdf0e10cSrcweir #include <svl/intitem.hxx> 33cdf0e10cSrcweir #include <svl/stritem.hxx> 34cdf0e10cSrcweir #include <svl/visitem.hxx> 35cdf0e10cSrcweir #include <com/sun/star/util/XURLTransformer.hpp> 36cdf0e10cSrcweir #include <com/sun/star/frame/XDispatchProviderInterceptor.hpp> 37cdf0e10cSrcweir #include <com/sun/star/frame/XDispatch.hpp> 38cdf0e10cSrcweir #include <com/sun/star/frame/XDispatchProvider.hpp> 39cdf0e10cSrcweir #include <com/sun/star/frame/XStatusListener.hpp> 40cdf0e10cSrcweir #include <com/sun/star/frame/FrameSearchFlag.hpp> 41cdf0e10cSrcweir #include <com/sun/star/frame/XDispatchProviderInterception.hpp> 42cdf0e10cSrcweir #include <com/sun/star/frame/FeatureStateEvent.hpp> 43cdf0e10cSrcweir #include <com/sun/star/frame/DispatchDescriptor.hpp> 44cdf0e10cSrcweir #include <com/sun/star/frame/XController.hpp> 45cdf0e10cSrcweir #include <comphelper/processfactory.hxx> 46cdf0e10cSrcweir #include <svtools/itemdel.hxx> 47cdf0e10cSrcweir 48cdf0e10cSrcweir #ifndef GCC 49cdf0e10cSrcweir #endif 50cdf0e10cSrcweir 51cdf0e10cSrcweir // wg. nInReschedule 52cdf0e10cSrcweir #include "appdata.hxx" 53cdf0e10cSrcweir #include <sfx2/bindings.hxx> 54cdf0e10cSrcweir #include <sfx2/msg.hxx> 55cdf0e10cSrcweir #include "statcach.hxx" 56cdf0e10cSrcweir #include <sfx2/ctrlitem.hxx> 57cdf0e10cSrcweir #include <sfx2/app.hxx> 58cdf0e10cSrcweir #include <sfx2/dispatch.hxx> 59cdf0e10cSrcweir #include <sfx2/request.hxx> 60cdf0e10cSrcweir #include <sfx2/objface.hxx> 61cdf0e10cSrcweir #include "sfxtypes.hxx" 62cdf0e10cSrcweir #include "workwin.hxx" 63cdf0e10cSrcweir #include <sfx2/unoctitm.hxx> 64cdf0e10cSrcweir #include <sfx2/sfx.hrc> 65cdf0e10cSrcweir #include <sfx2/sfxuno.hxx> 66cdf0e10cSrcweir #include <sfx2/viewfrm.hxx> 67cdf0e10cSrcweir #include <sfx2/objsh.hxx> 68cdf0e10cSrcweir #include <sfx2/msgpool.hxx> 69cdf0e10cSrcweir 70cdf0e10cSrcweir #include <comphelper/uieventslogger.hxx> 71cdf0e10cSrcweir #include <com/sun/star/frame/XModuleManager.hpp> 72cdf0e10cSrcweir 73cdf0e10cSrcweir 74cdf0e10cSrcweir using namespace ::com::sun::star; 75cdf0e10cSrcweir using namespace ::com::sun::star::uno; 76cdf0e10cSrcweir using namespace ::com::sun::star::util; 77cdf0e10cSrcweir 78cdf0e10cSrcweir DBG_NAME(SfxBindingsMsgPos) 79cdf0e10cSrcweir DBG_NAME(SfxBindingsUpdateServers) 80cdf0e10cSrcweir DBG_NAME(SfxBindingsCreateSet) 81cdf0e10cSrcweir DBG_NAME(SfxBindingsUpdateCtrl1) 82cdf0e10cSrcweir DBG_NAME(SfxBindingsUpdateCtrl2) 83cdf0e10cSrcweir DBG_NAME(SfxBindingsNextJob_Impl0) 84cdf0e10cSrcweir DBG_NAME(SfxBindingsNextJob_Impl) 85cdf0e10cSrcweir DBG_NAME(SfxBindingsUpdate_Impl) 86cdf0e10cSrcweir DBG_NAME(SfxBindingsInvalidateAll) 87cdf0e10cSrcweir 88cdf0e10cSrcweir //==================================================================== 89cdf0e10cSrcweir 90cdf0e10cSrcweir static sal_uInt16 nTimeOut = 300; 91cdf0e10cSrcweir 92cdf0e10cSrcweir #define TIMEOUT_FIRST nTimeOut 93cdf0e10cSrcweir #define TIMEOUT_UPDATING 20 94cdf0e10cSrcweir #define TIMEOUT_IDLE 2500 95cdf0e10cSrcweir 96cdf0e10cSrcweir static sal_uInt32 nCache1 = 0; 97cdf0e10cSrcweir static sal_uInt32 nCache2 = 0; 98cdf0e10cSrcweir 99cdf0e10cSrcweir typedef std::hash_map< sal_uInt16, bool > InvalidateSlotMap; 100cdf0e10cSrcweir 101cdf0e10cSrcweir //==================================================================== 102cdf0e10cSrcweir 103cdf0e10cSrcweir DECL_PTRARRAY(SfxStateCacheArr_Impl, SfxStateCache*, 32, 16) 104cdf0e10cSrcweir 105cdf0e10cSrcweir //==================================================================== 106cdf0e10cSrcweir 107cdf0e10cSrcweir class SfxAsyncExec_Impl 108cdf0e10cSrcweir { 109cdf0e10cSrcweir ::com::sun::star::util::URL aCommand; 110cdf0e10cSrcweir ::com::sun::star::uno::Reference< ::com::sun::star::frame::XDispatch > xDisp; 111cdf0e10cSrcweir Timer aTimer; 112cdf0e10cSrcweir 113cdf0e10cSrcweir public: 114cdf0e10cSrcweir 115cdf0e10cSrcweir SfxAsyncExec_Impl( const ::com::sun::star::util::URL& rCmd, const ::com::sun::star::uno::Reference< ::com::sun::star::frame::XDispatch >& rDisp ) 116cdf0e10cSrcweir : aCommand( rCmd ) 117cdf0e10cSrcweir , xDisp( rDisp ) 118cdf0e10cSrcweir { 119cdf0e10cSrcweir aTimer.SetTimeoutHdl( LINK(this, SfxAsyncExec_Impl, TimerHdl) ); 120cdf0e10cSrcweir aTimer.SetTimeout( 0 ); 121cdf0e10cSrcweir aTimer.Start(); 122cdf0e10cSrcweir } 123cdf0e10cSrcweir 124cdf0e10cSrcweir DECL_LINK( TimerHdl, Timer*); 125cdf0e10cSrcweir }; 126cdf0e10cSrcweir 127cdf0e10cSrcweir IMPL_LINK(SfxAsyncExec_Impl, TimerHdl, Timer*, pTimer) 128cdf0e10cSrcweir { 129cdf0e10cSrcweir (void)pTimer; // unused 130cdf0e10cSrcweir aTimer.Stop(); 131cdf0e10cSrcweir 132cdf0e10cSrcweir Sequence<beans::PropertyValue> aSeq; 133cdf0e10cSrcweir xDisp->dispatch( aCommand, aSeq ); 134cdf0e10cSrcweir 135cdf0e10cSrcweir delete this; 136cdf0e10cSrcweir return 0L; 137cdf0e10cSrcweir } 138cdf0e10cSrcweir 139cdf0e10cSrcweir class SfxBindings_Impl 140cdf0e10cSrcweir { 141cdf0e10cSrcweir public: 142cdf0e10cSrcweir ::com::sun::star::uno::Reference< ::com::sun::star::frame::XDispatchRecorder > xRecorder; 143cdf0e10cSrcweir ::com::sun::star::uno::Reference< ::com::sun::star::frame::XDispatchProvider > xProv; 144cdf0e10cSrcweir SfxUnoControllerArr_Impl* 145cdf0e10cSrcweir pUnoCtrlArr; 146cdf0e10cSrcweir SfxWorkWindow* pWorkWin; 147cdf0e10cSrcweir SfxBindings* pSubBindings; 148cdf0e10cSrcweir SfxBindings* pSuperBindings; 149cdf0e10cSrcweir SfxStateCacheArr_Impl* pCaches; // je ein cache fuer jede gebundene 150cdf0e10cSrcweir sal_uInt16 nCachedFunc1; // index der zuletzt gerufenen 151cdf0e10cSrcweir sal_uInt16 nCachedFunc2; // index der vorletzt gerufenen 152cdf0e10cSrcweir sal_uInt16 nMsgPos; // Message-Position, ab der zu aktualisieren ist 153cdf0e10cSrcweir SfxPopupAction ePopupAction; // in DeleteFloatinWindow() abgefragt 154cdf0e10cSrcweir sal_Bool bContextChanged; 155cdf0e10cSrcweir sal_Bool bMsgDirty; // wurde ein MessageServer invalidiert? 156cdf0e10cSrcweir sal_Bool bAllMsgDirty; // wurden die MessageServer invalidiert? 157cdf0e10cSrcweir sal_Bool bAllDirty; // nach InvalidateAll 158cdf0e10cSrcweir sal_Bool bCtrlReleased; // waehrend EnterRegistrations 159cdf0e10cSrcweir AutoTimer aTimer; // fuer volatile Slots 160cdf0e10cSrcweir sal_Bool bInUpdate; // fuer Assertions 161cdf0e10cSrcweir sal_Bool bInNextJob; // fuer Assertions 162cdf0e10cSrcweir sal_Bool bFirstRound; // Erste Runde im Update 163cdf0e10cSrcweir sal_uInt16 nFirstShell; // Shell, die in erster Runde bevorzugt wird 164cdf0e10cSrcweir sal_uInt16 nOwnRegLevel; // z"ahlt die echten Locks, ohne die der SuperBindings 165cdf0e10cSrcweir InvalidateSlotMap m_aInvalidateSlots; // store slots which are invalidated while in update 166cdf0e10cSrcweir }; 167cdf0e10cSrcweir 168cdf0e10cSrcweir //-------------------------------------------------------------------- 169cdf0e10cSrcweir 170cdf0e10cSrcweir struct SfxFoundCache_Impl 171cdf0e10cSrcweir { 172cdf0e10cSrcweir sal_uInt16 nSlotId; // die Slot-Id 173cdf0e10cSrcweir sal_uInt16 nWhichId; // falls verf"ugbar die Which-Id, sonst nSlotId 174cdf0e10cSrcweir const SfxSlot* pSlot; // Pointer auf den <Master-Slot> 175cdf0e10cSrcweir SfxStateCache* pCache; // Pointer auf den StatusCache, ggf. 0 176cdf0e10cSrcweir 177cdf0e10cSrcweir SfxFoundCache_Impl(): 178cdf0e10cSrcweir nSlotId(0), 179cdf0e10cSrcweir nWhichId(0), 180cdf0e10cSrcweir pSlot(0), 181cdf0e10cSrcweir pCache(0) 182cdf0e10cSrcweir {} 183cdf0e10cSrcweir 184cdf0e10cSrcweir SfxFoundCache_Impl(SfxFoundCache_Impl&r): 185cdf0e10cSrcweir nSlotId(r.nSlotId), 186cdf0e10cSrcweir nWhichId(r.nWhichId), 187cdf0e10cSrcweir pSlot(r.pSlot), 188cdf0e10cSrcweir pCache(r.pCache) 189cdf0e10cSrcweir {} 190cdf0e10cSrcweir 191cdf0e10cSrcweir SfxFoundCache_Impl(sal_uInt16 nS, sal_uInt16 nW, const SfxSlot *pS, SfxStateCache *pC ): 192cdf0e10cSrcweir nSlotId(nS), 193cdf0e10cSrcweir nWhichId(nW), 194cdf0e10cSrcweir pSlot(pS), 195cdf0e10cSrcweir pCache(pC) 196cdf0e10cSrcweir {} 197cdf0e10cSrcweir 198cdf0e10cSrcweir int operator<( const SfxFoundCache_Impl &r ) const 199cdf0e10cSrcweir { return nWhichId < r.nWhichId; } 200cdf0e10cSrcweir 201cdf0e10cSrcweir int operator==( const SfxFoundCache_Impl &r ) const 202cdf0e10cSrcweir { return nWhichId== r.nWhichId; } 203cdf0e10cSrcweir }; 204cdf0e10cSrcweir 205cdf0e10cSrcweir //-------------------------------------------------------------------------- 206cdf0e10cSrcweir 207cdf0e10cSrcweir SV_DECL_PTRARR_SORT_DEL(SfxFoundCacheArr_Impl, SfxFoundCache_Impl*, 16, 16 ) 208cdf0e10cSrcweir SV_IMPL_OP_PTRARR_SORT(SfxFoundCacheArr_Impl, SfxFoundCache_Impl*); 209cdf0e10cSrcweir 210cdf0e10cSrcweir //========================================================================== 211cdf0e10cSrcweir 212cdf0e10cSrcweir SfxBindings::SfxBindings() 213cdf0e10cSrcweir : pImp(new SfxBindings_Impl), 214cdf0e10cSrcweir pDispatcher(0), 215cdf0e10cSrcweir nRegLevel(1) // geht erst auf 0, wenn Dispatcher gesetzt 216cdf0e10cSrcweir { 217cdf0e10cSrcweir pImp->nMsgPos = 0; 218cdf0e10cSrcweir pImp->bAllMsgDirty = sal_True; 219cdf0e10cSrcweir pImp->bContextChanged = sal_False; 220cdf0e10cSrcweir pImp->bMsgDirty = sal_True; 221cdf0e10cSrcweir pImp->bAllDirty = sal_True; 222cdf0e10cSrcweir pImp->ePopupAction = SFX_POPUP_DELETE; 223cdf0e10cSrcweir pImp->nCachedFunc1 = 0; 224cdf0e10cSrcweir pImp->nCachedFunc2 = 0; 225cdf0e10cSrcweir pImp->bCtrlReleased = sal_False; 226cdf0e10cSrcweir pImp->bFirstRound = sal_False; 227cdf0e10cSrcweir pImp->bInNextJob = sal_False; 228cdf0e10cSrcweir pImp->bInUpdate = sal_False; 229cdf0e10cSrcweir pImp->pSubBindings = NULL; 230cdf0e10cSrcweir pImp->pSuperBindings = NULL; 231cdf0e10cSrcweir pImp->pWorkWin = NULL; 232cdf0e10cSrcweir pImp->pUnoCtrlArr = NULL; 233cdf0e10cSrcweir pImp->nOwnRegLevel = nRegLevel; 234cdf0e10cSrcweir 235cdf0e10cSrcweir // all caches are valid (no pending invalidate-job) 236cdf0e10cSrcweir // create the list of caches 237cdf0e10cSrcweir pImp->pCaches = new SfxStateCacheArr_Impl; 238cdf0e10cSrcweir pImp->aTimer.SetTimeoutHdl( LINK(this, SfxBindings, NextJob_Impl) ); 239cdf0e10cSrcweir } 240cdf0e10cSrcweir 241cdf0e10cSrcweir //==================================================================== 242cdf0e10cSrcweir 243cdf0e10cSrcweir SfxBindings::~SfxBindings() 244cdf0e10cSrcweir 245cdf0e10cSrcweir /* [Beschreibung] 246cdf0e10cSrcweir 247cdf0e10cSrcweir Destruktor der Klasse SfxBindings. Die eine, f"ur jede <SfxApplication> 248cdf0e10cSrcweir existierende Instanz wird von der <SfxApplication> nach Ausf"urhung 249cdf0e10cSrcweir von <SfxApplication::Exit()> automatisch zerst"ort. 250cdf0e10cSrcweir 251cdf0e10cSrcweir Noch existierende <SfxControllerItem> Instanzen, die bei dieser 252cdf0e10cSrcweir SfxBindings Instanz angemeldet sind, werden im Destruktor 253cdf0e10cSrcweir automatisch zerst"ort. Dies sind i.d.R. Floating-Toolboxen, Value-Sets 254cdf0e10cSrcweir etc. Arrays von SfxControllerItems d"urfen zu diesem Zeitpunkt nicht 255cdf0e10cSrcweir mehr exisitieren. 256cdf0e10cSrcweir */ 257cdf0e10cSrcweir 258cdf0e10cSrcweir { 259cdf0e10cSrcweir // Die SubBindings sollen ja nicht gelocked werden ! 260cdf0e10cSrcweir pImp->pSubBindings = NULL; 261cdf0e10cSrcweir 262cdf0e10cSrcweir ENTERREGISTRATIONS(); 263cdf0e10cSrcweir 264cdf0e10cSrcweir pImp->aTimer.Stop(); 265cdf0e10cSrcweir DeleteControllers_Impl(); 266cdf0e10cSrcweir 267cdf0e10cSrcweir // Caches selbst l"oschen 268cdf0e10cSrcweir sal_uInt16 nCount = pImp->pCaches->Count(); 269cdf0e10cSrcweir for ( sal_uInt16 nCache = 0; nCache < nCount; ++nCache ) 270cdf0e10cSrcweir delete pImp->pCaches->GetObject(nCache); 271cdf0e10cSrcweir 272cdf0e10cSrcweir DELETEZ( pImp->pWorkWin ); 273cdf0e10cSrcweir 274cdf0e10cSrcweir delete pImp->pCaches; 275cdf0e10cSrcweir delete pImp; 276cdf0e10cSrcweir } 277cdf0e10cSrcweir 278cdf0e10cSrcweir //-------------------------------------------------------------------- 279cdf0e10cSrcweir 280cdf0e10cSrcweir void SfxBindings::DeleteControllers_Impl() 281cdf0e10cSrcweir { 282cdf0e10cSrcweir // in der ersten Runde den SfxPopupWindows l"oschen 283cdf0e10cSrcweir sal_uInt16 nCount = pImp->pCaches->Count(); 284cdf0e10cSrcweir sal_uInt16 nCache; 285cdf0e10cSrcweir for ( nCache = 0; nCache < nCount; ++nCache ) 286cdf0e10cSrcweir { 287cdf0e10cSrcweir // merken wo man ist 288cdf0e10cSrcweir SfxStateCache *pCache = pImp->pCaches->GetObject(nCache); 289cdf0e10cSrcweir sal_uInt16 nSlotId = pCache->GetId(); 290cdf0e10cSrcweir 291cdf0e10cSrcweir // SfxPopupWindow l"oschen lassen 292cdf0e10cSrcweir pCache->DeleteFloatingWindows(); 293cdf0e10cSrcweir 294cdf0e10cSrcweir // da der Cache verkleinert worden sein kann, wiederaufsetzen 295cdf0e10cSrcweir sal_uInt16 nNewCount = pImp->pCaches->Count(); 296cdf0e10cSrcweir if ( nNewCount < nCount ) 297cdf0e10cSrcweir { 298cdf0e10cSrcweir nCache = GetSlotPos(nSlotId); 299cdf0e10cSrcweir if ( nCache >= nNewCount || 300cdf0e10cSrcweir nSlotId != pImp->pCaches->GetObject(nCache)->GetId() ) 301cdf0e10cSrcweir --nCache; 302cdf0e10cSrcweir nCount = nNewCount; 303cdf0e10cSrcweir } 304cdf0e10cSrcweir } 305cdf0e10cSrcweir 306cdf0e10cSrcweir // alle Caches l"oschen 307cdf0e10cSrcweir for ( nCache = pImp->pCaches->Count(); nCache > 0; --nCache ) 308cdf0e10cSrcweir { 309cdf0e10cSrcweir // Cache via ::com::sun::star::sdbcx::Index besorgen 310cdf0e10cSrcweir SfxStateCache *pCache = pImp->pCaches->GetObject(nCache-1); 311cdf0e10cSrcweir 312cdf0e10cSrcweir // alle Controller in dem Cache unbinden 313cdf0e10cSrcweir SfxControllerItem *pNext; 314cdf0e10cSrcweir for ( SfxControllerItem *pCtrl = pCache->GetItemLink(); 315cdf0e10cSrcweir pCtrl; pCtrl = pNext ) 316cdf0e10cSrcweir { 317cdf0e10cSrcweir pNext = pCtrl->GetItemLink(); 318cdf0e10cSrcweir pCtrl->UnBind(); 319cdf0e10cSrcweir } 320cdf0e10cSrcweir 321cdf0e10cSrcweir if ( pCache->GetInternalController() ) 322cdf0e10cSrcweir pCache->GetInternalController()->UnBind(); 323cdf0e10cSrcweir 324cdf0e10cSrcweir // Cache l"oschen 325cdf0e10cSrcweir if( nCache-1 < pImp->pCaches->Count() ) 326cdf0e10cSrcweir delete (*pImp->pCaches)[nCache-1]; 327cdf0e10cSrcweir pImp->pCaches->Remove(nCache-1, 1); 328cdf0e10cSrcweir } 329cdf0e10cSrcweir 330cdf0e10cSrcweir if( pImp->pUnoCtrlArr ) 331cdf0e10cSrcweir { 332cdf0e10cSrcweir sal_uInt16 nCtrlCount = pImp->pUnoCtrlArr->Count(); 333cdf0e10cSrcweir for ( sal_uInt16 n=nCtrlCount; n>0; n-- ) 334cdf0e10cSrcweir { 335cdf0e10cSrcweir SfxUnoControllerItem *pCtrl = (*pImp->pUnoCtrlArr)[n-1]; 336cdf0e10cSrcweir pCtrl->ReleaseBindings(); 337cdf0e10cSrcweir } 338cdf0e10cSrcweir 339cdf0e10cSrcweir DBG_ASSERT( !pImp->pUnoCtrlArr->Count(), "UnoControllerItems nicht entfernt!" ); 340cdf0e10cSrcweir DELETEZ( pImp->pUnoCtrlArr ); 341cdf0e10cSrcweir } 342cdf0e10cSrcweir } 343cdf0e10cSrcweir 344cdf0e10cSrcweir //-------------------------------------------------------------------- 345cdf0e10cSrcweir 346cdf0e10cSrcweir SfxPopupAction SfxBindings::GetPopupAction_Impl() const 347cdf0e10cSrcweir { 348cdf0e10cSrcweir return pImp->ePopupAction; 349cdf0e10cSrcweir } 350cdf0e10cSrcweir 351cdf0e10cSrcweir 352cdf0e10cSrcweir //-------------------------------------------------------------------- 353cdf0e10cSrcweir 354cdf0e10cSrcweir void SfxBindings::HidePopups( bool bHide ) 355cdf0e10cSrcweir { 356cdf0e10cSrcweir // SfxPopupWindows hiden 357cdf0e10cSrcweir HidePopupCtrls_Impl( bHide ); 358cdf0e10cSrcweir SfxBindings *pSub = pImp->pSubBindings; 359cdf0e10cSrcweir while ( pSub ) 360cdf0e10cSrcweir { 361cdf0e10cSrcweir pImp->pSubBindings->HidePopupCtrls_Impl( bHide ); 362cdf0e10cSrcweir pSub = pSub->pImp->pSubBindings; 363cdf0e10cSrcweir } 364cdf0e10cSrcweir 365cdf0e10cSrcweir // SfxChildWindows hiden 366cdf0e10cSrcweir DBG_ASSERT( pDispatcher, "HidePopups not allowed without dispatcher" ); 367cdf0e10cSrcweir if ( pImp->pWorkWin ) 368cdf0e10cSrcweir pImp->pWorkWin->HidePopups_Impl( bHide, sal_True ); 369cdf0e10cSrcweir } 370cdf0e10cSrcweir 371cdf0e10cSrcweir void SfxBindings::HidePopupCtrls_Impl( FASTBOOL bHide ) 372cdf0e10cSrcweir { 373cdf0e10cSrcweir if ( bHide ) 374cdf0e10cSrcweir { 375cdf0e10cSrcweir // SfxPopupWindows hiden 376cdf0e10cSrcweir pImp->ePopupAction = SFX_POPUP_HIDE; 377cdf0e10cSrcweir } 378cdf0e10cSrcweir else 379cdf0e10cSrcweir { 380cdf0e10cSrcweir // SfxPopupWindows showen 381cdf0e10cSrcweir pImp->ePopupAction = SFX_POPUP_SHOW; 382cdf0e10cSrcweir } 383cdf0e10cSrcweir 384cdf0e10cSrcweir for ( sal_uInt16 nCache = 0; nCache < pImp->pCaches->Count(); ++nCache ) 385cdf0e10cSrcweir pImp->pCaches->GetObject(nCache)->DeleteFloatingWindows(); 386cdf0e10cSrcweir pImp->ePopupAction = SFX_POPUP_DELETE; 387cdf0e10cSrcweir } 388cdf0e10cSrcweir 389cdf0e10cSrcweir //-------------------------------------------------------------------- 390cdf0e10cSrcweir 391cdf0e10cSrcweir void SfxBindings::Update_Impl 392cdf0e10cSrcweir ( 393cdf0e10cSrcweir SfxStateCache* pCache // der upzudatende SfxStatusCache 394cdf0e10cSrcweir ) 395cdf0e10cSrcweir { 396cdf0e10cSrcweir if( pCache->GetDispatch().is() && pCache->GetItemLink() ) 397cdf0e10cSrcweir { 398cdf0e10cSrcweir pCache->SetCachedState(sal_True); 399cdf0e10cSrcweir if ( !pCache->GetInternalController() ) 400cdf0e10cSrcweir return; 401cdf0e10cSrcweir } 402cdf0e10cSrcweir 403cdf0e10cSrcweir if ( !pDispatcher ) 404cdf0e10cSrcweir return; 405cdf0e10cSrcweir DBG_PROFSTART(SfxBindingsUpdate_Impl); 406cdf0e10cSrcweir 407cdf0e10cSrcweir // alle mit derselben Statusmethode zusammensammeln, die dirty sind 408cdf0e10cSrcweir SfxDispatcher &rDispat = *pDispatcher; 409cdf0e10cSrcweir const SfxSlot *pRealSlot = 0; 410cdf0e10cSrcweir const SfxSlotServer* pMsgServer = 0; 411cdf0e10cSrcweir SfxFoundCacheArr_Impl aFound; 412cdf0e10cSrcweir SfxItemSet *pSet = CreateSet_Impl( pCache, pRealSlot, &pMsgServer, aFound ); 413cdf0e10cSrcweir sal_Bool bUpdated = sal_False; 414cdf0e10cSrcweir if ( pSet ) 415cdf0e10cSrcweir { 416cdf0e10cSrcweir // Status erfragen 417cdf0e10cSrcweir if ( rDispat._FillState( *pMsgServer, *pSet, pRealSlot ) ) 418cdf0e10cSrcweir { 419cdf0e10cSrcweir // Status posten 420cdf0e10cSrcweir const SfxInterface *pInterface = 421cdf0e10cSrcweir rDispat.GetShell(pMsgServer->GetShellLevel())->GetInterface(); 422cdf0e10cSrcweir for ( sal_uInt16 nPos = 0; nPos < aFound.Count(); ++nPos ) 423cdf0e10cSrcweir { 424cdf0e10cSrcweir const SfxFoundCache_Impl *pFound = aFound[nPos]; 425cdf0e10cSrcweir sal_uInt16 nWhich = pFound->nWhichId; 426cdf0e10cSrcweir const SfxPoolItem *pItem = 0; 427cdf0e10cSrcweir SfxItemState eState = pSet->GetItemState(nWhich, sal_True, &pItem); 428cdf0e10cSrcweir if ( eState == SFX_ITEM_DEFAULT && SfxItemPool::IsWhich(nWhich) ) 429cdf0e10cSrcweir pItem = &pSet->Get(nWhich); 430cdf0e10cSrcweir UpdateControllers_Impl( pInterface, aFound[nPos], pItem, eState ); 431cdf0e10cSrcweir } 432cdf0e10cSrcweir bUpdated = sal_True; 433cdf0e10cSrcweir } 434cdf0e10cSrcweir 435cdf0e10cSrcweir delete pSet; 436cdf0e10cSrcweir } 437cdf0e10cSrcweir 438cdf0e10cSrcweir if ( !bUpdated && pCache ) 439cdf0e10cSrcweir { 440cdf0e10cSrcweir // Wenn pCache == NULL und kein SlotServer ( z.B. weil Dispatcher gelockt! ), 441cdf0e10cSrcweir // darf nat"urlich kein Update versucht werden 442cdf0e10cSrcweir SfxFoundCache_Impl aFoundCache( 443cdf0e10cSrcweir pCache->GetId(), 0, 444cdf0e10cSrcweir pRealSlot, pCache ); 445cdf0e10cSrcweir UpdateControllers_Impl( 0, &aFoundCache, 0, SFX_ITEM_DISABLED); 446cdf0e10cSrcweir } 447cdf0e10cSrcweir 448cdf0e10cSrcweir DBG_PROFSTOP(SfxBindingsUpdate_Impl); 449cdf0e10cSrcweir } 450cdf0e10cSrcweir 451cdf0e10cSrcweir //-------------------------------------------------------------------- 452cdf0e10cSrcweir 453cdf0e10cSrcweir void SfxBindings::InvalidateSlotsInMap_Impl() 454cdf0e10cSrcweir { 455cdf0e10cSrcweir InvalidateSlotMap::const_iterator pIter = pImp->m_aInvalidateSlots.begin(); 456cdf0e10cSrcweir while ( pIter != pImp->m_aInvalidateSlots.end() ) 457cdf0e10cSrcweir { 458cdf0e10cSrcweir Invalidate( pIter->first ); 459cdf0e10cSrcweir ++pIter; 460cdf0e10cSrcweir } 461cdf0e10cSrcweir pImp->m_aInvalidateSlots.clear(); 462cdf0e10cSrcweir } 463cdf0e10cSrcweir 464cdf0e10cSrcweir //-------------------------------------------------------------------- 465cdf0e10cSrcweir 466cdf0e10cSrcweir void SfxBindings::AddSlotToInvalidateSlotsMap_Impl( sal_uInt16 nId ) 467cdf0e10cSrcweir { 468cdf0e10cSrcweir pImp->m_aInvalidateSlots[nId] = sal_True; 469cdf0e10cSrcweir } 470cdf0e10cSrcweir 471cdf0e10cSrcweir //-------------------------------------------------------------------- 472cdf0e10cSrcweir 473cdf0e10cSrcweir void SfxBindings::Update 474cdf0e10cSrcweir ( 475cdf0e10cSrcweir sal_uInt16 nId // die gebundene und upzudatende Slot-Id 476cdf0e10cSrcweir ) 477cdf0e10cSrcweir { 478cdf0e10cSrcweir DBG_MEMTEST(); 479cdf0e10cSrcweir DBG_ASSERT( pImp->pCaches != 0, "SfxBindings not initialized" ); 480cdf0e10cSrcweir 481cdf0e10cSrcweir //!!TLX: Fuehrte zu Vorlagenkatalogstillstand 482cdf0e10cSrcweir // if ( nRegLevel ) 483cdf0e10cSrcweir // return; 484cdf0e10cSrcweir 485cdf0e10cSrcweir if ( pDispatcher ) 486cdf0e10cSrcweir pDispatcher->Flush(); 487cdf0e10cSrcweir 488cdf0e10cSrcweir if ( pImp->pSubBindings ) 489cdf0e10cSrcweir pImp->pSubBindings->Update( nId ); 490cdf0e10cSrcweir 491cdf0e10cSrcweir SfxStateCache* pCache = GetStateCache( nId ); 492cdf0e10cSrcweir if ( pCache ) 493cdf0e10cSrcweir { 494cdf0e10cSrcweir pImp->bInUpdate = sal_True; 495cdf0e10cSrcweir if ( pImp->bMsgDirty ) 496cdf0e10cSrcweir { 497cdf0e10cSrcweir UpdateSlotServer_Impl(); 498cdf0e10cSrcweir pCache = GetStateCache( nId ); 499cdf0e10cSrcweir } 500cdf0e10cSrcweir 501cdf0e10cSrcweir if (pCache) 502cdf0e10cSrcweir { 503cdf0e10cSrcweir sal_Bool bInternalUpdate = sal_True; 504cdf0e10cSrcweir if( pCache->GetDispatch().is() && pCache->GetItemLink() ) 505cdf0e10cSrcweir { 506cdf0e10cSrcweir pCache->SetCachedState(sal_True); 507cdf0e10cSrcweir bInternalUpdate = ( pCache->GetInternalController() != 0 ); 508cdf0e10cSrcweir } 509cdf0e10cSrcweir 510cdf0e10cSrcweir if ( bInternalUpdate ) 511cdf0e10cSrcweir { 512cdf0e10cSrcweir // Status erfragen 513cdf0e10cSrcweir const SfxSlotServer* pMsgServer = pCache->GetSlotServer(*pDispatcher, pImp->xProv); 514cdf0e10cSrcweir if ( !pCache->IsControllerDirty() && 515cdf0e10cSrcweir ( !pMsgServer || 516cdf0e10cSrcweir !pMsgServer->GetSlot()->IsMode(SFX_SLOT_VOLATILE) ) ) 517cdf0e10cSrcweir { 518cdf0e10cSrcweir pImp->bInUpdate = sal_False; 519cdf0e10cSrcweir InvalidateSlotsInMap_Impl(); 520cdf0e10cSrcweir return; 521cdf0e10cSrcweir } 522cdf0e10cSrcweir if (!pMsgServer) 523cdf0e10cSrcweir { 524cdf0e10cSrcweir pCache->SetState(SFX_ITEM_DISABLED, 0); 525cdf0e10cSrcweir pImp->bInUpdate = sal_False; 526cdf0e10cSrcweir InvalidateSlotsInMap_Impl(); 527cdf0e10cSrcweir return; 528cdf0e10cSrcweir } 529cdf0e10cSrcweir 530cdf0e10cSrcweir Update_Impl(pCache); 531cdf0e10cSrcweir } 532cdf0e10cSrcweir 533cdf0e10cSrcweir pImp->bAllDirty = sal_False; 534cdf0e10cSrcweir } 535cdf0e10cSrcweir 536cdf0e10cSrcweir pImp->bInUpdate = sal_False; 537cdf0e10cSrcweir InvalidateSlotsInMap_Impl(); 538cdf0e10cSrcweir } 539cdf0e10cSrcweir } 540cdf0e10cSrcweir 541cdf0e10cSrcweir //-------------------------------------------------------------------- 542cdf0e10cSrcweir 543cdf0e10cSrcweir void SfxBindings::Update() 544cdf0e10cSrcweir { 545cdf0e10cSrcweir DBG_MEMTEST(); 546cdf0e10cSrcweir DBG_ASSERT( pImp->pCaches != 0, "SfxBindings not initialized" ); 547cdf0e10cSrcweir 548cdf0e10cSrcweir if ( pImp->pSubBindings ) 549cdf0e10cSrcweir pImp->pSubBindings->Update(); 550cdf0e10cSrcweir 551cdf0e10cSrcweir if ( pDispatcher ) 552cdf0e10cSrcweir { 553cdf0e10cSrcweir if ( nRegLevel ) 554cdf0e10cSrcweir return; 555cdf0e10cSrcweir 556cdf0e10cSrcweir pImp->bInUpdate = sal_True; 557cdf0e10cSrcweir pDispatcher->Flush(); 558cdf0e10cSrcweir pDispatcher->Update_Impl(); 559cdf0e10cSrcweir while ( !NextJob_Impl(0) ) 560cdf0e10cSrcweir ; // loop 561cdf0e10cSrcweir pImp->bInUpdate = sal_False; 562cdf0e10cSrcweir InvalidateSlotsInMap_Impl(); 563cdf0e10cSrcweir } 564cdf0e10cSrcweir } 565cdf0e10cSrcweir 566cdf0e10cSrcweir //-------------------------------------------------------------------- 567cdf0e10cSrcweir 568cdf0e10cSrcweir void SfxBindings::SetState 569cdf0e10cSrcweir ( 570cdf0e10cSrcweir const SfxItemSet& rSet // zu setzende Status-Werte 571cdf0e10cSrcweir ) 572cdf0e10cSrcweir { 573cdf0e10cSrcweir // wenn gelockt, dann nur invalidieren 574cdf0e10cSrcweir if ( nRegLevel ) 575cdf0e10cSrcweir { 576cdf0e10cSrcweir SfxItemIter aIter(rSet); 577cdf0e10cSrcweir for ( const SfxPoolItem *pItem = aIter.FirstItem(); 578cdf0e10cSrcweir pItem; 579cdf0e10cSrcweir pItem = aIter.NextItem() ) 580cdf0e10cSrcweir Invalidate( pItem->Which() ); 581cdf0e10cSrcweir } 582cdf0e10cSrcweir else 583cdf0e10cSrcweir { 584cdf0e10cSrcweir // Status d"urfen nur angenommen werden, wenn alle Slot-Pointer gesetzt sind 585cdf0e10cSrcweir if ( pImp->bMsgDirty ) 586cdf0e10cSrcweir UpdateSlotServer_Impl(); 587cdf0e10cSrcweir 588cdf0e10cSrcweir // "uber das ItemSet iterieren, falls Slot gebunden, updaten 589cdf0e10cSrcweir //! Bug: WhichIter verwenden und ggf. VoidItems hochschicken 590cdf0e10cSrcweir SfxItemIter aIter(rSet); 591cdf0e10cSrcweir for ( const SfxPoolItem *pItem = aIter.FirstItem(); 592cdf0e10cSrcweir pItem; 593cdf0e10cSrcweir pItem = aIter.NextItem() ) 594cdf0e10cSrcweir { 595cdf0e10cSrcweir SfxStateCache* pCache = 596cdf0e10cSrcweir GetStateCache( rSet.GetPool()->GetSlotId(pItem->Which()) ); 597cdf0e10cSrcweir if ( pCache ) 598cdf0e10cSrcweir { 599cdf0e10cSrcweir // Status updaten 600cdf0e10cSrcweir if ( !pCache->IsControllerDirty() ) 601cdf0e10cSrcweir pCache->Invalidate(sal_False); 602cdf0e10cSrcweir pCache->SetState( SFX_ITEM_AVAILABLE, pItem ); 603cdf0e10cSrcweir 604cdf0e10cSrcweir //! nicht implementiert: Updates von EnumSlots via MasterSlots 605cdf0e10cSrcweir } 606cdf0e10cSrcweir } 607cdf0e10cSrcweir } 608cdf0e10cSrcweir } 609cdf0e10cSrcweir 610cdf0e10cSrcweir //-------------------------------------------------------------------- 611cdf0e10cSrcweir 612cdf0e10cSrcweir void SfxBindings::SetState 613cdf0e10cSrcweir ( 614cdf0e10cSrcweir const SfxPoolItem& rItem // zu setzender Status-Wert 615cdf0e10cSrcweir ) 616cdf0e10cSrcweir { 617cdf0e10cSrcweir if ( nRegLevel ) 618cdf0e10cSrcweir { 619cdf0e10cSrcweir Invalidate( rItem.Which() ); 620cdf0e10cSrcweir } 621cdf0e10cSrcweir else 622cdf0e10cSrcweir { 623cdf0e10cSrcweir // Status d"urfen nur angenommen werden, wenn alle Slot-Pointer gesetzt sind 624cdf0e10cSrcweir if ( pImp->bMsgDirty ) 625cdf0e10cSrcweir UpdateSlotServer_Impl(); 626cdf0e10cSrcweir 627cdf0e10cSrcweir // falls der Slot gebunden ist, updaten 628cdf0e10cSrcweir DBG_ASSERT( SfxItemPool::IsSlot( rItem.Which() ), 629cdf0e10cSrcweir "cannot set items with which-id" ); 630cdf0e10cSrcweir SfxStateCache* pCache = GetStateCache( rItem.Which() ); 631cdf0e10cSrcweir if ( pCache ) 632cdf0e10cSrcweir { 633cdf0e10cSrcweir // Status updaten 634cdf0e10cSrcweir if ( !pCache->IsControllerDirty() ) 635cdf0e10cSrcweir pCache->Invalidate(sal_False); 636cdf0e10cSrcweir pCache->SetState( SFX_ITEM_AVAILABLE, &rItem ); 637cdf0e10cSrcweir 638cdf0e10cSrcweir //! nicht implementiert: Updates von EnumSlots via MasterSlots 639cdf0e10cSrcweir } 640cdf0e10cSrcweir } 641cdf0e10cSrcweir } 642cdf0e10cSrcweir 643cdf0e10cSrcweir 644cdf0e10cSrcweir //-------------------------------------------------------------------- 645cdf0e10cSrcweir 646cdf0e10cSrcweir SfxStateCache* SfxBindings::GetAnyStateCache_Impl( sal_uInt16 nId ) 647cdf0e10cSrcweir { 648cdf0e10cSrcweir SfxStateCache* pCache = GetStateCache( nId ); 649cdf0e10cSrcweir if ( !pCache && pImp->pSubBindings ) 650cdf0e10cSrcweir return pImp->pSubBindings->GetAnyStateCache_Impl( nId ); 651cdf0e10cSrcweir return pCache; 652cdf0e10cSrcweir } 653cdf0e10cSrcweir 654cdf0e10cSrcweir SfxStateCache* SfxBindings::GetStateCache 655cdf0e10cSrcweir ( 656cdf0e10cSrcweir sal_uInt16 nId /* Slot-Id, deren SfxStatusCache gefunden 657cdf0e10cSrcweir werden soll */, 658cdf0e10cSrcweir sal_uInt16* pPos /* 0 bzw. Position, ab der die Bindings 659cdf0e10cSrcweir bin"ar durchsucht werden sollen. Liefert 660cdf0e10cSrcweir die Position zur"uck, an der nId gefunden 661cdf0e10cSrcweir wurde, bzw. an der es einfef"ugt werden 662cdf0e10cSrcweir w"urde. */ 663cdf0e10cSrcweir ) 664cdf0e10cSrcweir { 665cdf0e10cSrcweir DBG_MEMTEST(); 666cdf0e10cSrcweir DBG_ASSERT( pImp->pCaches != 0, "SfxBindings not initialized" ); 667cdf0e10cSrcweir // is the specified function bound? 668cdf0e10cSrcweir const sal_uInt16 nStart = ( pPos ? *pPos : 0 ); 669cdf0e10cSrcweir const sal_uInt16 nPos = GetSlotPos( nId, nStart ); 670cdf0e10cSrcweir 671cdf0e10cSrcweir if ( nPos < pImp->pCaches->Count() && 672cdf0e10cSrcweir (*pImp->pCaches)[nPos]->GetId() == nId ) 673cdf0e10cSrcweir { 674cdf0e10cSrcweir if ( pPos ) 675cdf0e10cSrcweir *pPos = nPos; 676cdf0e10cSrcweir return (*pImp->pCaches)[nPos]; 677cdf0e10cSrcweir } 678cdf0e10cSrcweir return 0; 679cdf0e10cSrcweir } 680cdf0e10cSrcweir 681cdf0e10cSrcweir //-------------------------------------------------------------------- 682cdf0e10cSrcweir 683cdf0e10cSrcweir void SfxBindings::InvalidateAll 684cdf0e10cSrcweir ( 685cdf0e10cSrcweir sal_Bool bWithMsg /* sal_True 686cdf0e10cSrcweir Slot-Server als ung"ultig markieren 687cdf0e10cSrcweir 688cdf0e10cSrcweir sal_False 689cdf0e10cSrcweir Slot-Server bleiben g"ultig */ 690cdf0e10cSrcweir ) 691cdf0e10cSrcweir { 692cdf0e10cSrcweir DBG_PROFSTART(SfxBindingsInvalidateAll); 693cdf0e10cSrcweir DBG_ASSERT( !pImp->bInUpdate, "SfxBindings::Invalidate while in update" ); 694cdf0e10cSrcweir 695cdf0e10cSrcweir DBG_MEMTEST(); 696cdf0e10cSrcweir 697cdf0e10cSrcweir if ( pImp->pSubBindings ) 698cdf0e10cSrcweir pImp->pSubBindings->InvalidateAll( bWithMsg ); 699cdf0e10cSrcweir 700cdf0e10cSrcweir // ist schon alles dirty gesetzt oder downing => nicht zu tun 701cdf0e10cSrcweir if ( !pDispatcher || 702cdf0e10cSrcweir ( pImp->bAllDirty && ( !bWithMsg || pImp->bAllMsgDirty ) ) || 703cdf0e10cSrcweir SFX_APP()->IsDowning() ) 704cdf0e10cSrcweir { 705cdf0e10cSrcweir DBG_PROFSTOP(SfxBindingsInvalidateAll); 706cdf0e10cSrcweir return; 707cdf0e10cSrcweir } 708cdf0e10cSrcweir 709cdf0e10cSrcweir pImp->bAllMsgDirty = pImp->bAllMsgDirty || bWithMsg; 710cdf0e10cSrcweir pImp->bMsgDirty = pImp->bMsgDirty || pImp->bAllMsgDirty || bWithMsg; 711cdf0e10cSrcweir pImp->bAllDirty = sal_True; 712cdf0e10cSrcweir 713cdf0e10cSrcweir for ( sal_uInt16 n = 0; n < pImp->pCaches->Count(); ++n ) 714cdf0e10cSrcweir pImp->pCaches->GetObject(n)->Invalidate(bWithMsg); 715cdf0e10cSrcweir /* 716cdf0e10cSrcweir ::com::sun::star::uno::Reference < ::com::sun::star::frame::XFrame > xFrame 717cdf0e10cSrcweir ( pDispatcher->GetFrame()->GetFrame().GetFrameInterface(), UNO_QUERY ); 718cdf0e10cSrcweir 719cdf0e10cSrcweir if ( bWithMsg && xFrame.is() ) 720cdf0e10cSrcweir xFrame->contextChanged(); 721cdf0e10cSrcweir */ 722cdf0e10cSrcweir pImp->nMsgPos = 0; 723cdf0e10cSrcweir if ( !nRegLevel ) 724cdf0e10cSrcweir { 725cdf0e10cSrcweir pImp->aTimer.Stop(); 726cdf0e10cSrcweir pImp->aTimer.SetTimeout(TIMEOUT_FIRST); 727cdf0e10cSrcweir pImp->aTimer.Start(); 728cdf0e10cSrcweir // pImp->bFirstRound = sal_True; 729cdf0e10cSrcweir // pImp->nFirstShell = 0; 730cdf0e10cSrcweir } 731cdf0e10cSrcweir 732cdf0e10cSrcweir DBG_PROFSTOP(SfxBindingsInvalidateAll); 733cdf0e10cSrcweir } 734cdf0e10cSrcweir 735cdf0e10cSrcweir //-------------------------------------------------------------------- 736cdf0e10cSrcweir 737cdf0e10cSrcweir void SfxBindings::Invalidate 738cdf0e10cSrcweir ( 739cdf0e10cSrcweir const sal_uInt16* pIds /* numerisch sortiertes 0-terminiertes Array 740cdf0e10cSrcweir von Slot-Ids (einzel, nicht als Paare!) */ 741cdf0e10cSrcweir ) 742cdf0e10cSrcweir { 743cdf0e10cSrcweir DBG_PROFSTART(SfxBindingsInvalidateAll); 744cdf0e10cSrcweir // DBG_ASSERT( !pImp->bInUpdate, "SfxBindings::Invalidate while in update" ); 745cdf0e10cSrcweir 746cdf0e10cSrcweir DBG_MEMTEST(); 747cdf0e10cSrcweir 748cdf0e10cSrcweir if ( pImp->bInUpdate ) 749cdf0e10cSrcweir { 750cdf0e10cSrcweir sal_Int32 i = 0; 751cdf0e10cSrcweir while ( pIds[i] != 0 ) 752cdf0e10cSrcweir AddSlotToInvalidateSlotsMap_Impl( pIds[i++] ); 753cdf0e10cSrcweir 754cdf0e10cSrcweir if ( pImp->pSubBindings ) 755cdf0e10cSrcweir pImp->pSubBindings->Invalidate( pIds ); 756cdf0e10cSrcweir return; 757cdf0e10cSrcweir } 758cdf0e10cSrcweir 759cdf0e10cSrcweir if ( pImp->pSubBindings ) 760cdf0e10cSrcweir pImp->pSubBindings->Invalidate( pIds ); 761cdf0e10cSrcweir 762cdf0e10cSrcweir // ist schon alles dirty gesetzt oder downing => nicht zu tun 763cdf0e10cSrcweir if ( !pDispatcher || pImp->bAllDirty || SFX_APP()->IsDowning() ) 764cdf0e10cSrcweir return; 765cdf0e10cSrcweir 766cdf0e10cSrcweir // in immer kleiner werdenden Berichen bin"ar suchen 767cdf0e10cSrcweir for ( sal_uInt16 n = GetSlotPos(*pIds); 768cdf0e10cSrcweir *pIds && n < pImp->pCaches->Count(); 769cdf0e10cSrcweir n = GetSlotPos(*pIds, n) ) 770cdf0e10cSrcweir { 771cdf0e10cSrcweir // falls SID "uberhaupt gebunden ist, den Cache invalidieren 772cdf0e10cSrcweir SfxStateCache *pCache = pImp->pCaches->GetObject(n); 773cdf0e10cSrcweir if ( pCache->GetId() == *pIds ) 774cdf0e10cSrcweir pCache->Invalidate(sal_False); 775cdf0e10cSrcweir 776cdf0e10cSrcweir // n"achste SID 777cdf0e10cSrcweir if ( !*++pIds ) 778cdf0e10cSrcweir break; 779cdf0e10cSrcweir DBG_ASSERT( *pIds > *(pIds-1), "pIds unsorted" ); 780cdf0e10cSrcweir } 781cdf0e10cSrcweir 782cdf0e10cSrcweir // falls nicht gelockt, Update-Timer starten 783cdf0e10cSrcweir pImp->nMsgPos = 0; 784cdf0e10cSrcweir if ( !nRegLevel ) 785cdf0e10cSrcweir { 786cdf0e10cSrcweir pImp->aTimer.Stop(); 787cdf0e10cSrcweir pImp->aTimer.SetTimeout(TIMEOUT_FIRST); 788cdf0e10cSrcweir pImp->aTimer.Start(); 789cdf0e10cSrcweir // pImp->bFirstRound = sal_True; 790cdf0e10cSrcweir // pImp->nFirstShell = 0; 791cdf0e10cSrcweir } 792cdf0e10cSrcweir 793cdf0e10cSrcweir DBG_PROFSTOP(SfxBindingsInvalidateAll); 794cdf0e10cSrcweir } 795cdf0e10cSrcweir 796cdf0e10cSrcweir //-------------------------------------------------------------------- 797cdf0e10cSrcweir 798cdf0e10cSrcweir void SfxBindings::InvalidateShell 799cdf0e10cSrcweir ( 800cdf0e10cSrcweir const SfxShell& rSh /* Die <SfxShell>, deren Slot-Ids 801cdf0e10cSrcweir invalidiert werden sollen. */, 802cdf0e10cSrcweir 803cdf0e10cSrcweir sal_Bool bDeep /* sal_True 804cdf0e10cSrcweir auch die, von der SfxShell 805cdf0e10cSrcweir ererbten Slot-Ids werden invalidert 806cdf0e10cSrcweir 807cdf0e10cSrcweir sal_False 808cdf0e10cSrcweir die ererbten und nicht "uberladenen 809cdf0e10cSrcweir Slot-Ids werden invalidiert */ 810cdf0e10cSrcweir //! MI: z. Zt. immer bDeep 811cdf0e10cSrcweir ) 812cdf0e10cSrcweir { 813cdf0e10cSrcweir DBG_ASSERT( !pImp->bInUpdate, "SfxBindings::Invalidate while in update" ); 814cdf0e10cSrcweir 815cdf0e10cSrcweir if ( pImp->pSubBindings ) 816cdf0e10cSrcweir pImp->pSubBindings->InvalidateShell( rSh, bDeep ); 817cdf0e10cSrcweir 818cdf0e10cSrcweir if ( !pDispatcher || pImp->bAllDirty || SFX_APP()->IsDowning() ) 819cdf0e10cSrcweir return; 820cdf0e10cSrcweir 821cdf0e10cSrcweir DBG_PROFSTART(SfxBindingsInvalidateAll); 822cdf0e10cSrcweir DBG_MEMTEST(); 823cdf0e10cSrcweir 824cdf0e10cSrcweir // Jetzt schon flushen, wird in GetShellLevel(rSh) sowieso gemacht; wichtig, 825cdf0e10cSrcweir // damit pImp->bAll(Msg)Dirty korrekt gesetzt ist 826cdf0e10cSrcweir pDispatcher->Flush(); 827cdf0e10cSrcweir 828cdf0e10cSrcweir if ( !pDispatcher || 829cdf0e10cSrcweir ( pImp->bAllDirty && pImp->bAllMsgDirty ) || 830cdf0e10cSrcweir SFX_APP()->IsDowning() ) 831cdf0e10cSrcweir { 832cdf0e10cSrcweir // Wenn sowieso demn"achst alle Server geholt werden 833cdf0e10cSrcweir return; 834cdf0e10cSrcweir } 835cdf0e10cSrcweir 836cdf0e10cSrcweir // Level finden 837cdf0e10cSrcweir sal_uInt16 nLevel = pDispatcher->GetShellLevel(rSh); 838cdf0e10cSrcweir if ( nLevel != USHRT_MAX ) 839cdf0e10cSrcweir { 840cdf0e10cSrcweir for ( sal_uInt16 n = 0; n < pImp->pCaches->Count(); ++n ) 841cdf0e10cSrcweir { 842cdf0e10cSrcweir SfxStateCache *pCache = pImp->pCaches->GetObject(n); 843cdf0e10cSrcweir const SfxSlotServer *pMsgServer = 844cdf0e10cSrcweir pCache->GetSlotServer(*pDispatcher, pImp->xProv); 845cdf0e10cSrcweir if ( pMsgServer && pMsgServer->GetShellLevel() == nLevel ) 846cdf0e10cSrcweir pCache->Invalidate(sal_False); 847cdf0e10cSrcweir } 848cdf0e10cSrcweir pImp->nMsgPos = 0; 849cdf0e10cSrcweir if ( !nRegLevel ) 850cdf0e10cSrcweir { 851cdf0e10cSrcweir pImp->aTimer.Stop(); 852cdf0e10cSrcweir pImp->aTimer.SetTimeout(TIMEOUT_FIRST); 853cdf0e10cSrcweir pImp->aTimer.Start(); 854cdf0e10cSrcweir pImp->bFirstRound = sal_True; 855cdf0e10cSrcweir pImp->nFirstShell = nLevel; 856cdf0e10cSrcweir } 857cdf0e10cSrcweir } 858cdf0e10cSrcweir 859cdf0e10cSrcweir DBG_PROFSTOP(SfxBindingsInvalidateAll); 860cdf0e10cSrcweir } 861cdf0e10cSrcweir 862cdf0e10cSrcweir //-------------------------------------------------------------------- 863cdf0e10cSrcweir 864cdf0e10cSrcweir void SfxBindings::Invalidate 865cdf0e10cSrcweir ( 866cdf0e10cSrcweir sal_uInt16 nId // zu invalidierende Slot-Id 867cdf0e10cSrcweir ) 868cdf0e10cSrcweir { 869cdf0e10cSrcweir DBG_MEMTEST(); 870cdf0e10cSrcweir // DBG_ASSERT( !pImp->bInUpdate, "SfxBindings::Invalidate while in update" ); 871cdf0e10cSrcweir 872cdf0e10cSrcweir if ( pImp->bInUpdate ) 873cdf0e10cSrcweir { 874cdf0e10cSrcweir AddSlotToInvalidateSlotsMap_Impl( nId ); 875cdf0e10cSrcweir if ( pImp->pSubBindings ) 876cdf0e10cSrcweir pImp->pSubBindings->Invalidate( nId ); 877cdf0e10cSrcweir return; 878cdf0e10cSrcweir } 879cdf0e10cSrcweir 880cdf0e10cSrcweir if ( pImp->pSubBindings ) 881cdf0e10cSrcweir pImp->pSubBindings->Invalidate( nId ); 882cdf0e10cSrcweir 883cdf0e10cSrcweir if ( !pDispatcher || pImp->bAllDirty || SFX_APP()->IsDowning() ) 884cdf0e10cSrcweir return; 885cdf0e10cSrcweir 886cdf0e10cSrcweir SfxStateCache* pCache = GetStateCache(nId); 887cdf0e10cSrcweir if ( pCache ) 888cdf0e10cSrcweir { 889cdf0e10cSrcweir pCache->Invalidate(sal_False); 890cdf0e10cSrcweir pImp->nMsgPos = Min(GetSlotPos(nId), pImp->nMsgPos); 891cdf0e10cSrcweir if ( !nRegLevel ) 892cdf0e10cSrcweir { 893cdf0e10cSrcweir pImp->aTimer.Stop(); 894cdf0e10cSrcweir pImp->aTimer.SetTimeout(TIMEOUT_FIRST); 895cdf0e10cSrcweir pImp->aTimer.Start(); 896cdf0e10cSrcweir } 897cdf0e10cSrcweir } 898cdf0e10cSrcweir } 899cdf0e10cSrcweir 900cdf0e10cSrcweir //-------------------------------------------------------------------- 901cdf0e10cSrcweir 902cdf0e10cSrcweir void SfxBindings::Invalidate 903cdf0e10cSrcweir ( 904cdf0e10cSrcweir sal_uInt16 nId, // zu invalidierende Slot-Id 905cdf0e10cSrcweir sal_Bool bWithItem, // StateCache clearen ? 906cdf0e10cSrcweir sal_Bool bWithMsg // SlotServer neu holen ? 907cdf0e10cSrcweir ) 908cdf0e10cSrcweir { 909cdf0e10cSrcweir DBG_MEMTEST(); 910cdf0e10cSrcweir DBG_ASSERT( !pImp->bInUpdate, "SfxBindings::Invalidate while in update" ); 911cdf0e10cSrcweir 912cdf0e10cSrcweir if ( pImp->pSubBindings ) 913cdf0e10cSrcweir pImp->pSubBindings->Invalidate( nId, bWithItem, bWithMsg ); 914cdf0e10cSrcweir 915cdf0e10cSrcweir if ( SFX_APP()->IsDowning() ) 916cdf0e10cSrcweir return; 917cdf0e10cSrcweir 918cdf0e10cSrcweir SfxStateCache* pCache = GetStateCache(nId); 919cdf0e10cSrcweir if ( pCache ) 920cdf0e10cSrcweir { 921cdf0e10cSrcweir if ( bWithItem ) 922cdf0e10cSrcweir pCache->ClearCache(); 923cdf0e10cSrcweir pCache->Invalidate(bWithMsg); 924cdf0e10cSrcweir 925cdf0e10cSrcweir if ( !pDispatcher || pImp->bAllDirty ) 926cdf0e10cSrcweir return; 927cdf0e10cSrcweir 928cdf0e10cSrcweir pImp->nMsgPos = Min(GetSlotPos(nId), pImp->nMsgPos); 929cdf0e10cSrcweir if ( !nRegLevel ) 930cdf0e10cSrcweir { 931cdf0e10cSrcweir pImp->aTimer.Stop(); 932cdf0e10cSrcweir pImp->aTimer.SetTimeout(TIMEOUT_FIRST); 933cdf0e10cSrcweir pImp->aTimer.Start(); 934cdf0e10cSrcweir } 935cdf0e10cSrcweir } 936cdf0e10cSrcweir } 937cdf0e10cSrcweir 938cdf0e10cSrcweir //-------------------------------------------------------------------- 939cdf0e10cSrcweir 940cdf0e10cSrcweir sal_Bool SfxBindings::IsBound( sal_uInt16 nSlotId, sal_uInt16 nStartSearchAt ) 941cdf0e10cSrcweir { 942cdf0e10cSrcweir DBG_MEMTEST(); 943cdf0e10cSrcweir DBG_ASSERT( pImp->pCaches != 0, "SfxBindings not initialized" ); 944cdf0e10cSrcweir return GetStateCache(nSlotId, &nStartSearchAt ) != 0; 945cdf0e10cSrcweir } 946cdf0e10cSrcweir 947cdf0e10cSrcweir //-------------------------------------------------------------------- 948cdf0e10cSrcweir 949cdf0e10cSrcweir sal_uInt16 SfxBindings::GetSlotPos( sal_uInt16 nId, sal_uInt16 nStartSearchAt ) 950cdf0e10cSrcweir { 951cdf0e10cSrcweir DBG_MEMTEST(); 952cdf0e10cSrcweir DBG_ASSERT( pImp->pCaches != 0, "SfxBindings not initialized" ); 953cdf0e10cSrcweir DBG_PROFSTART(SfxBindingsMsgPos); 954cdf0e10cSrcweir 955cdf0e10cSrcweir // answer immediately if a function-seek comes repeated 956cdf0e10cSrcweir if ( pImp->nCachedFunc1 < pImp->pCaches->Count() && 957cdf0e10cSrcweir (*pImp->pCaches)[pImp->nCachedFunc1]->GetId() == nId ) 958cdf0e10cSrcweir { 959cdf0e10cSrcweir ++nCache1; 960cdf0e10cSrcweir DBG_PROFSTOP(SfxBindingsMsgPos); 961cdf0e10cSrcweir return pImp->nCachedFunc1; 962cdf0e10cSrcweir } 963cdf0e10cSrcweir if ( pImp->nCachedFunc2 < pImp->pCaches->Count() && 964cdf0e10cSrcweir (*pImp->pCaches)[pImp->nCachedFunc2]->GetId() == nId ) 965cdf0e10cSrcweir { 966cdf0e10cSrcweir ++nCache2; 967cdf0e10cSrcweir 968cdf0e10cSrcweir // swap the caches 969cdf0e10cSrcweir sal_uInt16 nTemp = pImp->nCachedFunc1; 970cdf0e10cSrcweir pImp->nCachedFunc1 = pImp->nCachedFunc2; 971cdf0e10cSrcweir pImp->nCachedFunc2 = nTemp; 972cdf0e10cSrcweir DBG_PROFSTOP(SfxBindingsMsgPos); 973cdf0e10cSrcweir return pImp->nCachedFunc1; 974cdf0e10cSrcweir } 975cdf0e10cSrcweir 976cdf0e10cSrcweir // binary search, if not found, seek to target-position 977cdf0e10cSrcweir if ( pImp->pCaches->Count() <= nStartSearchAt ) 978cdf0e10cSrcweir { 979cdf0e10cSrcweir DBG_PROFSTOP(SfxBindingsMsgPos); 980cdf0e10cSrcweir return 0; 981cdf0e10cSrcweir } 982cdf0e10cSrcweir if ( pImp->pCaches->Count() == (nStartSearchAt+1) ) 983cdf0e10cSrcweir { 984cdf0e10cSrcweir DBG_PROFSTOP(SfxBindingsMsgPos); 985cdf0e10cSrcweir return (*pImp->pCaches)[nStartSearchAt]->GetId() >= nId ? 0 : 1; 986cdf0e10cSrcweir } 987cdf0e10cSrcweir sal_uInt16 nLow = nStartSearchAt; 988cdf0e10cSrcweir sal_uInt16 nMid = 0; 989cdf0e10cSrcweir sal_uInt16 nHigh = 0; 990cdf0e10cSrcweir sal_Bool bFound = sal_False; 991cdf0e10cSrcweir nHigh = pImp->pCaches->Count() - 1; 992cdf0e10cSrcweir while ( !bFound && nLow <= nHigh ) 993cdf0e10cSrcweir { 994cdf0e10cSrcweir nMid = (nLow + nHigh) >> 1; 995cdf0e10cSrcweir DBG_ASSERT( nMid < pImp->pCaches->Count(), "bsearch ist buggy" ); 996cdf0e10cSrcweir int nDiff = (int) nId - (int) ( ((*pImp->pCaches)[nMid])->GetId() ); 997cdf0e10cSrcweir if ( nDiff < 0) 998cdf0e10cSrcweir { if ( nMid == 0 ) 999cdf0e10cSrcweir break; 1000cdf0e10cSrcweir nHigh = nMid - 1; 1001cdf0e10cSrcweir } 1002cdf0e10cSrcweir else if ( nDiff > 0 ) 1003cdf0e10cSrcweir { nLow = nMid + 1; 1004cdf0e10cSrcweir if ( nLow == 0 ) 1005cdf0e10cSrcweir break; 1006cdf0e10cSrcweir } 1007cdf0e10cSrcweir else 1008cdf0e10cSrcweir bFound = sal_True; 1009cdf0e10cSrcweir } 1010cdf0e10cSrcweir sal_uInt16 nPos = bFound ? nMid : nLow; 1011cdf0e10cSrcweir DBG_ASSERT( nPos <= pImp->pCaches->Count(), "" ); 1012cdf0e10cSrcweir DBG_ASSERT( nPos == pImp->pCaches->Count() || 1013cdf0e10cSrcweir nId <= (*pImp->pCaches)[nPos]->GetId(), "" ); 1014cdf0e10cSrcweir DBG_ASSERT( nPos == nStartSearchAt || 1015cdf0e10cSrcweir nId > (*pImp->pCaches)[nPos-1]->GetId(), "" ); 1016cdf0e10cSrcweir DBG_ASSERT( ( (nPos+1) >= pImp->pCaches->Count() ) || 1017cdf0e10cSrcweir nId < (*pImp->pCaches)[nPos+1]->GetId(), "" ); 1018cdf0e10cSrcweir pImp->nCachedFunc2 = pImp->nCachedFunc1; 1019cdf0e10cSrcweir pImp->nCachedFunc1 = nPos; 1020cdf0e10cSrcweir DBG_PROFSTOP(SfxBindingsMsgPos); 1021cdf0e10cSrcweir return nPos; 1022cdf0e10cSrcweir } 1023cdf0e10cSrcweir //-------------------------------------------------------------------- 1024cdf0e10cSrcweir void SfxBindings::RegisterInternal_Impl( SfxControllerItem& rItem ) 1025cdf0e10cSrcweir { 1026cdf0e10cSrcweir Register_Impl( rItem, sal_True ); 1027cdf0e10cSrcweir 1028cdf0e10cSrcweir } 1029cdf0e10cSrcweir 1030cdf0e10cSrcweir void SfxBindings::Register( SfxControllerItem& rItem ) 1031cdf0e10cSrcweir { 1032cdf0e10cSrcweir Register_Impl( rItem, sal_False ); 1033cdf0e10cSrcweir } 1034cdf0e10cSrcweir 1035cdf0e10cSrcweir void SfxBindings::Register_Impl( SfxControllerItem& rItem, sal_Bool bInternal ) 1036cdf0e10cSrcweir { 1037cdf0e10cSrcweir DBG_MEMTEST(); 1038*5d65efa0SAndre Fischer // DBG_ASSERT( nRegLevel > 0, "registration without EnterRegistrations" ); 1039cdf0e10cSrcweir DBG_ASSERT( !pImp->bInNextJob, "SfxBindings::Register while status-updating" ); 1040cdf0e10cSrcweir 1041cdf0e10cSrcweir // insert new cache if it does not already exist 1042cdf0e10cSrcweir sal_uInt16 nId = rItem.GetId(); 1043cdf0e10cSrcweir sal_uInt16 nPos = GetSlotPos(nId); 1044cdf0e10cSrcweir if ( nPos >= pImp->pCaches->Count() || 1045cdf0e10cSrcweir (*pImp->pCaches)[nPos]->GetId() != nId ) 1046cdf0e10cSrcweir { 1047cdf0e10cSrcweir SfxStateCache* pCache = new SfxStateCache(nId); 1048cdf0e10cSrcweir pImp->pCaches->Insert( nPos, pCache ); 1049cdf0e10cSrcweir DBG_ASSERT( nPos == 0 || 1050cdf0e10cSrcweir (*pImp->pCaches)[nPos]->GetId() > 1051cdf0e10cSrcweir (*pImp->pCaches)[nPos-1]->GetId(), "" ); 1052cdf0e10cSrcweir DBG_ASSERT( (nPos == pImp->pCaches->Count()-1) || 1053cdf0e10cSrcweir (*pImp->pCaches)[nPos]->GetId() < 1054cdf0e10cSrcweir (*pImp->pCaches)[nPos+1]->GetId(), "" ); 1055cdf0e10cSrcweir pImp->bMsgDirty = sal_True; 1056cdf0e10cSrcweir } 1057cdf0e10cSrcweir 1058cdf0e10cSrcweir // enqueue the new binding 1059cdf0e10cSrcweir if ( bInternal ) 1060cdf0e10cSrcweir { 1061cdf0e10cSrcweir (*pImp->pCaches)[nPos]->SetInternalController( &rItem ); 1062cdf0e10cSrcweir } 1063cdf0e10cSrcweir else 1064cdf0e10cSrcweir { 1065cdf0e10cSrcweir SfxControllerItem *pOldItem = (*pImp->pCaches)[nPos]->ChangeItemLink(&rItem); 1066cdf0e10cSrcweir rItem.ChangeItemLink(pOldItem); 1067cdf0e10cSrcweir } 1068cdf0e10cSrcweir } 1069cdf0e10cSrcweir 1070cdf0e10cSrcweir //-------------------------------------------------------------------- 1071cdf0e10cSrcweir 1072cdf0e10cSrcweir void SfxBindings::Release( SfxControllerItem& rItem ) 1073cdf0e10cSrcweir { 1074cdf0e10cSrcweir DBG_MEMTEST(); 1075cdf0e10cSrcweir DBG_ASSERT( pImp->pCaches != 0, "SfxBindings not initialized" ); 1076cdf0e10cSrcweir //! DBG_ASSERT( nRegLevel > 0, "release without EnterRegistrations" ); 1077cdf0e10cSrcweir DBG_ASSERT( !pImp->bInNextJob, "SfxBindings::Release while status-updating" ); 1078cdf0e10cSrcweir ENTERREGISTRATIONS(); 1079cdf0e10cSrcweir 1080cdf0e10cSrcweir // find the bound function 1081cdf0e10cSrcweir sal_uInt16 nId = rItem.GetId(); 1082cdf0e10cSrcweir sal_uInt16 nPos = GetSlotPos(nId); 1083cdf0e10cSrcweir SfxStateCache* pCache = (*pImp->pCaches)[nPos]; 1084cdf0e10cSrcweir if ( pCache->GetId() == nId ) 1085cdf0e10cSrcweir { 1086cdf0e10cSrcweir if ( pCache->GetInternalController() == &rItem ) 1087cdf0e10cSrcweir { 1088cdf0e10cSrcweir pCache->ReleaseInternalController(); 1089cdf0e10cSrcweir } 1090cdf0e10cSrcweir else 1091cdf0e10cSrcweir { 1092cdf0e10cSrcweir // is this the first binding in the list? 1093cdf0e10cSrcweir SfxControllerItem* pItem = pCache->GetItemLink(); 1094cdf0e10cSrcweir if ( pItem == &rItem ) 1095cdf0e10cSrcweir pCache->ChangeItemLink( rItem.GetItemLink() ); 1096cdf0e10cSrcweir else 1097cdf0e10cSrcweir { 1098cdf0e10cSrcweir // search the binding in the list 1099cdf0e10cSrcweir while ( pItem && pItem->GetItemLink() != &rItem ) 1100cdf0e10cSrcweir pItem = pItem->GetItemLink(); 1101cdf0e10cSrcweir 1102cdf0e10cSrcweir // unlink it if it was found 1103cdf0e10cSrcweir if ( pItem ) 1104cdf0e10cSrcweir pItem->ChangeItemLink( rItem.GetItemLink() ); 1105cdf0e10cSrcweir } 1106cdf0e10cSrcweir } 1107cdf0e10cSrcweir 1108cdf0e10cSrcweir // was this the last controller? 1109cdf0e10cSrcweir if ( pCache->GetItemLink() == 0 && !pCache->GetInternalController() ) 1110cdf0e10cSrcweir { 1111cdf0e10cSrcweir #ifdef slow 1112cdf0e10cSrcweir // remove the BoundFunc 1113cdf0e10cSrcweir delete (*pImp->pCaches)[nPos]; 1114cdf0e10cSrcweir pImp->pCaches->Remove(nPos, 1); 1115cdf0e10cSrcweir #endif 1116cdf0e10cSrcweir pImp->bCtrlReleased = sal_True; 1117cdf0e10cSrcweir } 1118cdf0e10cSrcweir } 1119cdf0e10cSrcweir 1120cdf0e10cSrcweir LEAVEREGISTRATIONS(); 1121cdf0e10cSrcweir } 1122cdf0e10cSrcweir 1123cdf0e10cSrcweir //-------------------------------------------------------------------- 1124cdf0e10cSrcweir const SfxPoolItem* SfxBindings::ExecuteSynchron( sal_uInt16 nId, const SfxPoolItem** ppItems, sal_uInt16 nModi, 1125cdf0e10cSrcweir const SfxPoolItem **ppInternalArgs ) 1126cdf0e10cSrcweir { 1127cdf0e10cSrcweir DBG_MEMTEST(); 1128cdf0e10cSrcweir DBG_ASSERT( pImp->pCaches != 0, "SfxBindings not initialized" ); 1129cdf0e10cSrcweir 1130cdf0e10cSrcweir if( !nId || !pDispatcher ) 1131cdf0e10cSrcweir return NULL; 1132cdf0e10cSrcweir 1133cdf0e10cSrcweir return Execute_Impl( nId, ppItems, nModi, SFX_CALLMODE_SYNCHRON, ppInternalArgs ); 1134cdf0e10cSrcweir } 1135cdf0e10cSrcweir 1136cdf0e10cSrcweir sal_Bool SfxBindings::Execute( sal_uInt16 nId, const SfxPoolItem** ppItems, sal_uInt16 nModi, SfxCallMode nCallMode, 1137cdf0e10cSrcweir const SfxPoolItem **ppInternalArgs ) 1138cdf0e10cSrcweir { 1139cdf0e10cSrcweir DBG_MEMTEST(); 1140cdf0e10cSrcweir DBG_ASSERT( pImp->pCaches != 0, "SfxBindings not initialized" ); 1141cdf0e10cSrcweir 1142cdf0e10cSrcweir if( !nId || !pDispatcher ) 1143cdf0e10cSrcweir return sal_False; 1144cdf0e10cSrcweir 1145cdf0e10cSrcweir const SfxPoolItem* pRet = Execute_Impl( nId, ppItems, nModi, nCallMode, ppInternalArgs ); 1146cdf0e10cSrcweir return ( pRet != 0 ); 1147cdf0e10cSrcweir } 1148cdf0e10cSrcweir 1149cdf0e10cSrcweir void SfxBindings::ExecuteGlobal_Impl( sal_uInt16 nId ) 1150cdf0e10cSrcweir { 1151cdf0e10cSrcweir if( nId && pDispatcher ) 1152cdf0e10cSrcweir Execute_Impl( nId, NULL, 0, SFX_CALLMODE_ASYNCHRON, NULL, sal_True ); 1153cdf0e10cSrcweir } 1154cdf0e10cSrcweir 1155cdf0e10cSrcweir const SfxPoolItem* SfxBindings::Execute_Impl( sal_uInt16 nId, const SfxPoolItem** ppItems, sal_uInt16 nModi, SfxCallMode nCallMode, 1156cdf0e10cSrcweir const SfxPoolItem **ppInternalArgs, sal_Bool bGlobalOnly ) 1157cdf0e10cSrcweir { 1158cdf0e10cSrcweir SfxStateCache *pCache = GetStateCache( nId ); 1159cdf0e10cSrcweir if ( !pCache ) 1160cdf0e10cSrcweir { 1161cdf0e10cSrcweir SfxBindings *pBind = pImp->pSubBindings; 1162cdf0e10cSrcweir while ( pBind ) 1163cdf0e10cSrcweir { 1164cdf0e10cSrcweir if ( pBind->GetStateCache( nId ) ) 1165cdf0e10cSrcweir return pBind->Execute_Impl( nId, ppItems, nModi, nCallMode, ppInternalArgs, bGlobalOnly ); 1166cdf0e10cSrcweir pBind = pBind->pImp->pSubBindings; 1167cdf0e10cSrcweir }; 1168cdf0e10cSrcweir } 1169cdf0e10cSrcweir 1170cdf0e10cSrcweir SfxDispatcher &rDispatcher = *pDispatcher; 1171cdf0e10cSrcweir rDispatcher.Flush(); 1172cdf0e10cSrcweir rDispatcher.GetFrame(); // -Wall is this required??? 1173cdf0e10cSrcweir 1174cdf0e10cSrcweir // get SlotServer (Slot+ShellLevel) and Shell from cache 1175cdf0e10cSrcweir sal_Bool bDeleteCache = sal_False; 1176cdf0e10cSrcweir if ( !pCache ) 1177cdf0e10cSrcweir { 1178cdf0e10cSrcweir // Execution of non cached slots (Accelerators don't use Controllers) 1179cdf0e10cSrcweir // slot is uncached, use SlotCache to handle external dispatch providers 1180cdf0e10cSrcweir pCache = new SfxStateCache( nId ); 1181cdf0e10cSrcweir pCache->GetSlotServer( rDispatcher, pImp->xProv ); 1182cdf0e10cSrcweir bDeleteCache = sal_True; 1183cdf0e10cSrcweir } 1184cdf0e10cSrcweir 1185cdf0e10cSrcweir if ( pCache && pCache->GetDispatch().is() ) 1186cdf0e10cSrcweir { 1187cdf0e10cSrcweir DBG_ASSERT( !ppInternalArgs, "Internal args get lost when dispatched!" ); 1188cdf0e10cSrcweir 1189cdf0e10cSrcweir SfxItemPool &rPool = GetDispatcher()->GetFrame()->GetObjectShell()->GetPool(); 1190cdf0e10cSrcweir SfxRequest aReq( nId, nCallMode, rPool ); 1191cdf0e10cSrcweir aReq.SetModifier( nModi ); 1192cdf0e10cSrcweir if( ppItems ) 1193cdf0e10cSrcweir while( *ppItems ) 1194cdf0e10cSrcweir aReq.AppendItem( **ppItems++ ); 1195cdf0e10cSrcweir 1196cdf0e10cSrcweir // cache binds to an external dispatch provider 1197cdf0e10cSrcweir pCache->Dispatch( aReq.GetArgs(), nCallMode == SFX_CALLMODE_SYNCHRON ); 1198cdf0e10cSrcweir if ( bDeleteCache ) 1199cdf0e10cSrcweir DELETEZ( pCache ); 1200cdf0e10cSrcweir SfxPoolItem *pVoid = new SfxVoidItem( nId ); 1201cdf0e10cSrcweir DeleteItemOnIdle( pVoid ); 1202cdf0e10cSrcweir return pVoid; 1203cdf0e10cSrcweir } 1204cdf0e10cSrcweir 1205cdf0e10cSrcweir // slot is handled internally by SfxDispatcher 1206cdf0e10cSrcweir if ( pImp->bMsgDirty ) 1207cdf0e10cSrcweir UpdateSlotServer_Impl(); 1208cdf0e10cSrcweir 1209cdf0e10cSrcweir SfxShell *pShell=0; 1210cdf0e10cSrcweir const SfxSlot *pSlot=0; 1211cdf0e10cSrcweir 1212cdf0e10cSrcweir // if slot was uncached, we should have created a cache in this method! 1213cdf0e10cSrcweir DBG_ASSERT( pCache, "This code needs a cache!"); 1214cdf0e10cSrcweir const SfxSlotServer* pServer = pCache ? pCache->GetSlotServer( rDispatcher, pImp->xProv ) : 0; 1215cdf0e10cSrcweir if ( !pServer ) 1216cdf0e10cSrcweir { 1217cdf0e10cSrcweir return NULL; 1218cdf0e10cSrcweir } 1219cdf0e10cSrcweir else 1220cdf0e10cSrcweir { 1221cdf0e10cSrcweir pShell = rDispatcher.GetShell( pServer->GetShellLevel() ); 1222cdf0e10cSrcweir pSlot = pServer->GetSlot(); 1223cdf0e10cSrcweir } 1224cdf0e10cSrcweir 1225cdf0e10cSrcweir if ( bGlobalOnly ) 1226cdf0e10cSrcweir if ( !pShell->ISA(SfxModule) && !pShell->ISA(SfxApplication) && !pShell->ISA(SfxViewFrame) ) 1227cdf0e10cSrcweir return NULL; 1228cdf0e10cSrcweir 1229cdf0e10cSrcweir SfxItemPool &rPool = pShell->GetPool(); 1230cdf0e10cSrcweir SfxRequest aReq( nId, nCallMode, rPool ); 1231cdf0e10cSrcweir aReq.SetModifier( nModi ); 1232cdf0e10cSrcweir if( ppItems ) 1233cdf0e10cSrcweir while( *ppItems ) 1234cdf0e10cSrcweir aReq.AppendItem( **ppItems++ ); 1235cdf0e10cSrcweir if ( ppInternalArgs ) 1236cdf0e10cSrcweir { 1237cdf0e10cSrcweir SfxAllItemSet aSet( rPool ); 1238cdf0e10cSrcweir for ( const SfxPoolItem **pArg = ppInternalArgs; *pArg; ++pArg ) 1239cdf0e10cSrcweir aSet.Put( **pArg ); 1240cdf0e10cSrcweir aReq.SetInternalArgs_Impl( aSet ); 1241cdf0e10cSrcweir } 1242cdf0e10cSrcweir 1243cdf0e10cSrcweir Execute_Impl( aReq, pSlot, pShell ); 1244cdf0e10cSrcweir 1245cdf0e10cSrcweir const SfxPoolItem* pRet = aReq.GetReturnValue(); 1246cdf0e10cSrcweir if ( !pRet ) 1247cdf0e10cSrcweir { 1248cdf0e10cSrcweir SfxPoolItem *pVoid = new SfxVoidItem( nId ); 1249cdf0e10cSrcweir DeleteItemOnIdle( pVoid ); 1250cdf0e10cSrcweir pRet = pVoid; 1251cdf0e10cSrcweir } 1252cdf0e10cSrcweir 1253cdf0e10cSrcweir if ( bDeleteCache ) 1254cdf0e10cSrcweir delete pCache; 1255cdf0e10cSrcweir 1256cdf0e10cSrcweir return pRet; 1257cdf0e10cSrcweir } 1258cdf0e10cSrcweir 1259cdf0e10cSrcweir void SfxBindings::Execute_Impl( SfxRequest& aReq, const SfxSlot* pSlot, SfxShell* pShell ) 1260cdf0e10cSrcweir { 1261cdf0e10cSrcweir SfxItemPool &rPool = pShell->GetPool(); 1262cdf0e10cSrcweir 1263cdf0e10cSrcweir if ( SFX_KIND_ENUM == pSlot->GetKind() ) 1264cdf0e10cSrcweir { 1265cdf0e10cSrcweir // bei Enum-Slots muss der Master mit dem Wert des Enums executet werden 1266cdf0e10cSrcweir const SfxSlot *pRealSlot = pShell->GetInterface()->GetRealSlot(pSlot); 1267cdf0e10cSrcweir const sal_uInt16 nSlotId = pRealSlot->GetSlotId(); 1268cdf0e10cSrcweir aReq.SetSlot( nSlotId ); 1269cdf0e10cSrcweir aReq.AppendItem( SfxAllEnumItem( rPool.GetWhich(nSlotId), pSlot->GetValue() ) ); 1270cdf0e10cSrcweir pDispatcher->_Execute( *pShell, *pRealSlot, aReq, aReq.GetCallMode() | SFX_CALLMODE_RECORD ); 1271cdf0e10cSrcweir } 1272cdf0e10cSrcweir else if ( SFX_KIND_ATTR == pSlot->GetKind() ) 1273cdf0e10cSrcweir { 1274cdf0e10cSrcweir // bei Attr-Slots muss der Which-Wert gemapped werden 1275cdf0e10cSrcweir const sal_uInt16 nSlotId = pSlot->GetSlotId(); 1276cdf0e10cSrcweir aReq.SetSlot( nSlotId ); 1277cdf0e10cSrcweir if ( pSlot->IsMode(SFX_SLOT_TOGGLE) ) 1278cdf0e10cSrcweir { 1279cdf0e10cSrcweir // an togglebare-Attribs (Bools) wird der Wert angeheangt 1280cdf0e10cSrcweir sal_uInt16 nWhich = pSlot->GetWhich(rPool); 1281cdf0e10cSrcweir SfxItemSet aSet(rPool, nWhich, nWhich, 0); 1282cdf0e10cSrcweir SfxStateFunc aFunc = pSlot->GetStateFnc(); 1283cdf0e10cSrcweir pShell->CallState( aFunc, aSet ); 1284cdf0e10cSrcweir const SfxPoolItem *pOldItem; 1285cdf0e10cSrcweir SfxItemState eState = aSet.GetItemState(nWhich, sal_True, &pOldItem); 1286cdf0e10cSrcweir if ( eState == SFX_ITEM_DISABLED ) 1287cdf0e10cSrcweir return; 1288cdf0e10cSrcweir 1289cdf0e10cSrcweir if ( SFX_ITEM_AVAILABLE == eState && SfxItemPool::IsWhich(nWhich) ) 1290cdf0e10cSrcweir pOldItem = &aSet.Get(nWhich); 1291cdf0e10cSrcweir 1292cdf0e10cSrcweir if ( SFX_ITEM_SET == eState || 1293cdf0e10cSrcweir ( SFX_ITEM_AVAILABLE == eState && 1294cdf0e10cSrcweir SfxItemPool::IsWhich(nWhich) && 1295cdf0e10cSrcweir pOldItem ) ) 1296cdf0e10cSrcweir { 1297cdf0e10cSrcweir if ( pOldItem->ISA(SfxBoolItem) ) 1298cdf0e10cSrcweir { 1299cdf0e10cSrcweir // wir koennen Bools toggeln 1300cdf0e10cSrcweir sal_Bool bOldValue = ((const SfxBoolItem *)pOldItem)->GetValue(); 1301cdf0e10cSrcweir SfxBoolItem *pNewItem = (SfxBoolItem*) (pOldItem->Clone()); 1302cdf0e10cSrcweir pNewItem->SetValue( !bOldValue ); 1303cdf0e10cSrcweir aReq.AppendItem( *pNewItem ); 1304cdf0e10cSrcweir delete pNewItem; 1305cdf0e10cSrcweir } 1306cdf0e10cSrcweir else if ( pOldItem->ISA(SfxEnumItemInterface) && 1307cdf0e10cSrcweir ((SfxEnumItemInterface *)pOldItem)->HasBoolValue()) 1308cdf0e10cSrcweir { 1309cdf0e10cSrcweir // und Enums mit Bool-Interface 1310cdf0e10cSrcweir SfxEnumItemInterface *pNewItem = 1311cdf0e10cSrcweir (SfxEnumItemInterface*) (pOldItem->Clone()); 1312cdf0e10cSrcweir pNewItem->SetBoolValue(!((SfxEnumItemInterface *)pOldItem)->GetBoolValue()); 1313cdf0e10cSrcweir aReq.AppendItem( *pNewItem ); 1314cdf0e10cSrcweir delete pNewItem; 1315cdf0e10cSrcweir } 1316cdf0e10cSrcweir else { 1317cdf0e10cSrcweir DBG_ERROR( "Toggle only for Enums and Bools allowed" ); 1318cdf0e10cSrcweir } 1319cdf0e10cSrcweir } 1320cdf0e10cSrcweir else if ( SFX_ITEM_DONTCARE == eState ) 1321cdf0e10cSrcweir { 1322cdf0e10cSrcweir // ein Status-Item per Factory erzeugen 1323cdf0e10cSrcweir SfxPoolItem *pNewItem = pSlot->GetType()->CreateItem(); 1324cdf0e10cSrcweir DBG_ASSERT( pNewItem, "Toggle an Slot ohne ItemFactory" ); 1325cdf0e10cSrcweir pNewItem->SetWhich( nWhich ); 1326cdf0e10cSrcweir 1327cdf0e10cSrcweir if ( pNewItem->ISA(SfxBoolItem) ) 1328cdf0e10cSrcweir { 1329cdf0e10cSrcweir // wir koennen Bools toggeln 1330cdf0e10cSrcweir ((SfxBoolItem*)pNewItem)->SetValue( sal_True ); 1331cdf0e10cSrcweir aReq.AppendItem( *pNewItem ); 1332cdf0e10cSrcweir } 1333cdf0e10cSrcweir else if ( pNewItem->ISA(SfxEnumItemInterface) && 1334cdf0e10cSrcweir ((SfxEnumItemInterface *)pNewItem)->HasBoolValue()) 1335cdf0e10cSrcweir { 1336cdf0e10cSrcweir // und Enums mit Bool-Interface 1337cdf0e10cSrcweir ((SfxEnumItemInterface*)pNewItem)->SetBoolValue(sal_True); 1338cdf0e10cSrcweir aReq.AppendItem( *pNewItem ); 1339cdf0e10cSrcweir } 1340cdf0e10cSrcweir else { 1341cdf0e10cSrcweir DBG_ERROR( "Toggle only for Enums and Bools allowed" ); 1342cdf0e10cSrcweir } 1343cdf0e10cSrcweir delete pNewItem; 1344cdf0e10cSrcweir } 1345cdf0e10cSrcweir else { 1346cdf0e10cSrcweir DBG_ERROR( "suspicious Toggle-Slot" ); 1347cdf0e10cSrcweir } 1348cdf0e10cSrcweir } 1349cdf0e10cSrcweir 1350cdf0e10cSrcweir pDispatcher->_Execute( *pShell, *pSlot, aReq, aReq.GetCallMode() | SFX_CALLMODE_RECORD ); 1351cdf0e10cSrcweir } 1352cdf0e10cSrcweir else 1353cdf0e10cSrcweir pDispatcher->_Execute( *pShell, *pSlot, aReq, aReq.GetCallMode() | SFX_CALLMODE_RECORD ); 1354cdf0e10cSrcweir } 1355cdf0e10cSrcweir 1356cdf0e10cSrcweir //-------------------------------------------------------------------- 1357cdf0e10cSrcweir 1358cdf0e10cSrcweir void SfxBindings::UpdateSlotServer_Impl() 1359cdf0e10cSrcweir { 1360cdf0e10cSrcweir DBG_PROFSTART(SfxBindingsUpdateServers); 1361cdf0e10cSrcweir DBG_MEMTEST(); 1362cdf0e10cSrcweir DBG_ASSERT( pImp->pCaches != 0, "SfxBindings not initialized" ); 1363cdf0e10cSrcweir 1364cdf0e10cSrcweir // synchronisieren 1365cdf0e10cSrcweir pDispatcher->Flush(); 1366cdf0e10cSrcweir // pDispatcher->Update_Impl(); 1367cdf0e10cSrcweir 1368cdf0e10cSrcweir if ( pImp->bAllMsgDirty ) 1369cdf0e10cSrcweir { 1370cdf0e10cSrcweir if ( !nRegLevel ) 1371cdf0e10cSrcweir { 1372cdf0e10cSrcweir ::com::sun::star::uno::Reference < ::com::sun::star::frame::XFrame > xFrame 1373cdf0e10cSrcweir ( pDispatcher->GetFrame()->GetFrame().GetFrameInterface(), UNO_QUERY ); 1374cdf0e10cSrcweir //if ( xFrame.is() ) 1375cdf0e10cSrcweir // xFrame->contextChanged(); 1376cdf0e10cSrcweir pImp->bContextChanged = sal_False; 1377cdf0e10cSrcweir } 1378cdf0e10cSrcweir else 1379cdf0e10cSrcweir pImp->bContextChanged = sal_True; 1380cdf0e10cSrcweir } 1381cdf0e10cSrcweir 1382cdf0e10cSrcweir const sal_uInt16 nCount = pImp->pCaches->Count(); 1383cdf0e10cSrcweir for(sal_uInt16 i = 0; i < nCount; ++i) 1384cdf0e10cSrcweir { 1385cdf0e10cSrcweir SfxStateCache *pCache = pImp->pCaches->GetObject(i); 1386cdf0e10cSrcweir pCache->GetSlotServer(*pDispatcher, pImp->xProv); 1387cdf0e10cSrcweir } 1388cdf0e10cSrcweir pImp->bMsgDirty = pImp->bAllMsgDirty = sal_False; 1389cdf0e10cSrcweir 1390cdf0e10cSrcweir Broadcast( SfxSimpleHint(SFX_HINT_DOCCHANGED) ); 1391cdf0e10cSrcweir 1392cdf0e10cSrcweir DBG_PROFSTOP(SfxBindingsUpdateServers); 1393cdf0e10cSrcweir } 1394cdf0e10cSrcweir 1395cdf0e10cSrcweir //-------------------------------------------------------------------- 1396cdf0e10cSrcweir 1397cdf0e10cSrcweir #ifdef WNT 1398cdf0e10cSrcweir int __cdecl CmpUS_Impl(const void *p1, const void *p2) 1399cdf0e10cSrcweir #else 1400cdf0e10cSrcweir int CmpUS_Impl(const void *p1, const void *p2) 1401cdf0e10cSrcweir #endif 1402cdf0e10cSrcweir 1403cdf0e10cSrcweir /* [Beschreibung] 1404cdf0e10cSrcweir 1405cdf0e10cSrcweir Interne Vergleichsfunktion fuer qsort. 1406cdf0e10cSrcweir */ 1407cdf0e10cSrcweir 1408cdf0e10cSrcweir { 1409cdf0e10cSrcweir return *(sal_uInt16 *)p1 - *(sal_uInt16 *)p2; 1410cdf0e10cSrcweir } 1411cdf0e10cSrcweir 1412cdf0e10cSrcweir //-------------------------------------------------------------------- 1413cdf0e10cSrcweir 1414cdf0e10cSrcweir SfxItemSet* SfxBindings::CreateSet_Impl 1415cdf0e10cSrcweir ( 1416cdf0e10cSrcweir SfxStateCache*& pCache, // in: Status-Cache von nId 1417cdf0e10cSrcweir const SfxSlot*& pRealSlot, // out: RealSlot zu nId 1418cdf0e10cSrcweir const SfxSlotServer** pMsgServer, // out: Slot-Server zu nId 1419cdf0e10cSrcweir SfxFoundCacheArr_Impl& rFound // out: Liste der Caches der Siblings 1420cdf0e10cSrcweir ) 1421cdf0e10cSrcweir { 1422cdf0e10cSrcweir DBG_MEMTEST(); 1423cdf0e10cSrcweir DBG_ASSERT( pImp->pCaches != 0, "SfxBindings not initialized" ); 1424cdf0e10cSrcweir 1425cdf0e10cSrcweir DBG_ASSERT( !pImp->bMsgDirty, "CreateSet_Impl mit dirty MessageServer" ); 1426cdf0e10cSrcweir 1427cdf0e10cSrcweir const SfxSlotServer* pMsgSvr = pCache->GetSlotServer(*pDispatcher, pImp->xProv); 1428cdf0e10cSrcweir if(!pMsgSvr || !pDispatcher) 1429cdf0e10cSrcweir return 0; 1430cdf0e10cSrcweir 1431cdf0e10cSrcweir DBG_PROFSTART(SfxBindingsCreateSet); 1432cdf0e10cSrcweir pRealSlot = 0; 1433cdf0e10cSrcweir *pMsgServer = pMsgSvr; 1434cdf0e10cSrcweir 1435cdf0e10cSrcweir sal_uInt16 nShellLevel = pMsgSvr->GetShellLevel(); 1436cdf0e10cSrcweir SfxShell *pShell = pDispatcher->GetShell( nShellLevel ); 1437cdf0e10cSrcweir if ( !pShell ) // seltener GPF beim Browsen durch Update aus Inet-Notify 1438cdf0e10cSrcweir return 0; 1439cdf0e10cSrcweir 1440cdf0e10cSrcweir SfxItemPool &rPool = pShell->GetPool(); 1441cdf0e10cSrcweir 1442cdf0e10cSrcweir // hole die Status-Methode, von der pCache bedient wird 1443cdf0e10cSrcweir SfxStateFunc pFnc = 0; 1444cdf0e10cSrcweir const SfxInterface *pInterface = pShell->GetInterface(); 1445cdf0e10cSrcweir if ( SFX_KIND_ENUM == pMsgSvr->GetSlot()->GetKind() ) 1446cdf0e10cSrcweir { 1447cdf0e10cSrcweir pRealSlot = pInterface->GetRealSlot(pMsgSvr->GetSlot()); 1448cdf0e10cSrcweir pCache = GetStateCache( pRealSlot->GetSlotId() ); 1449cdf0e10cSrcweir // DBG_ASSERT( pCache, "Kein Slotcache fuer den Masterslot gefunden!" ); 1450cdf0e10cSrcweir } 1451cdf0e10cSrcweir else 1452cdf0e10cSrcweir pRealSlot = pMsgSvr->GetSlot(); 1453cdf0e10cSrcweir 1454cdf0e10cSrcweir // 1455cdf0e10cSrcweir // Achtung: pCache darf auch NULL sein !!! 1456cdf0e10cSrcweir // 1457cdf0e10cSrcweir 1458cdf0e10cSrcweir pFnc = pRealSlot->GetStateFnc(); 1459cdf0e10cSrcweir 1460cdf0e10cSrcweir // der RealSlot ist immer drin 1461cdf0e10cSrcweir const SfxFoundCache_Impl *pFound = new SfxFoundCache_Impl( 1462cdf0e10cSrcweir pRealSlot->GetSlotId(), pRealSlot->GetWhich(rPool), pRealSlot, pCache ); 1463cdf0e10cSrcweir rFound.Insert( pFound ); 1464cdf0e10cSrcweir 1465cdf0e10cSrcweir sal_uInt16 nSlot = pRealSlot->GetSlotId(); 1466cdf0e10cSrcweir if ( !(nSlot >= SID_VERB_START && nSlot <= SID_VERB_END) ) 1467cdf0e10cSrcweir { 1468cdf0e10cSrcweir pInterface = pInterface->GetRealInterfaceForSlot( pRealSlot ); 1469cdf0e10cSrcweir DBG_ASSERT (pInterface,"Slot in angegebener Shell nicht gefunden!"); 1470cdf0e10cSrcweir } 1471cdf0e10cSrcweir 1472cdf0e10cSrcweir // Durchsuche die Bindings nach den von derselben Funktion bedienten Slots. 1473cdf0e10cSrcweir // Daf"ur kommen nur Slots in Frage, die es im gefundenen Interface gibt. 1474cdf0e10cSrcweir 1475cdf0e10cSrcweir // Die Position des Statecaches im StateCache-Array 1476cdf0e10cSrcweir sal_uInt16 nCachePos = pImp->nMsgPos; 1477cdf0e10cSrcweir const SfxSlot *pSibling = pRealSlot->GetNextSlot(); 1478cdf0e10cSrcweir 1479cdf0e10cSrcweir // Die Slots eines Interfaces sind im Kreis verkettet 1480cdf0e10cSrcweir while ( pSibling > pRealSlot ) 1481cdf0e10cSrcweir { 1482cdf0e10cSrcweir SfxStateFunc pSiblingFnc=0; 1483cdf0e10cSrcweir SfxStateCache *pSiblingCache = 1484cdf0e10cSrcweir GetStateCache( pSibling->GetSlotId(), &nCachePos ); 1485cdf0e10cSrcweir 1486cdf0e10cSrcweir // Ist der Slot "uberhaupt gecached ? 1487cdf0e10cSrcweir if ( pSiblingCache ) 1488cdf0e10cSrcweir { 1489cdf0e10cSrcweir const SfxSlotServer *pServ = pSiblingCache->GetSlotServer(*pDispatcher, pImp->xProv); 1490cdf0e10cSrcweir if ( pServ && pServ->GetShellLevel() == nShellLevel ) 1491cdf0e10cSrcweir pSiblingFnc = pServ->GetSlot()->GetStateFnc(); 1492cdf0e10cSrcweir } 1493cdf0e10cSrcweir 1494cdf0e10cSrcweir // Mu\s der Slot "uberhaupt upgedatet werden ? 1495cdf0e10cSrcweir bool bInsert = pSiblingCache && pSiblingCache->IsControllerDirty(); 1496cdf0e10cSrcweir 1497cdf0e10cSrcweir // Bugfix #26161#: Es reicht nicht, nach der selben Shell zu fragen !! 1498cdf0e10cSrcweir bool bSameMethod = pSiblingCache && pFnc == pSiblingFnc; 1499cdf0e10cSrcweir 1500cdf0e10cSrcweir // Wenn der Slot ein nicht-dirty MasterSlot ist, dann ist vielleicht 1501cdf0e10cSrcweir // einer seiner Slaves dirty ? Dann wird der Masterslot doch eingef"ugt. 1502cdf0e10cSrcweir if ( !bInsert && bSameMethod && pSibling->GetLinkedSlot() ) 1503cdf0e10cSrcweir { 1504cdf0e10cSrcweir // auch Slave-Slots auf Binding pru"fen 1505cdf0e10cSrcweir const SfxSlot* pFirstSlave = pSibling->GetLinkedSlot(); 1506cdf0e10cSrcweir for ( const SfxSlot *pSlaveSlot = pFirstSlave; 1507cdf0e10cSrcweir !bInsert; 1508cdf0e10cSrcweir pSlaveSlot = pSlaveSlot->GetNextSlot()) 1509cdf0e10cSrcweir { 1510cdf0e10cSrcweir // Die Slaves zeigen auf ihren Master 1511cdf0e10cSrcweir DBG_ASSERT(pSlaveSlot->GetLinkedSlot() == pSibling, 1512cdf0e10cSrcweir "Falsche Master/Slave-Beziehung!"); 1513cdf0e10cSrcweir 1514cdf0e10cSrcweir sal_uInt16 nCurMsgPos = pImp->nMsgPos; 1515cdf0e10cSrcweir const SfxStateCache *pSlaveCache = 1516cdf0e10cSrcweir GetStateCache( pSlaveSlot->GetSlotId(), &nCurMsgPos ); 1517cdf0e10cSrcweir 1518cdf0e10cSrcweir // Ist der Slave-Slot gecached und dirty ? 1519cdf0e10cSrcweir bInsert = pSlaveCache && pSlaveCache->IsControllerDirty(); 1520cdf0e10cSrcweir 1521cdf0e10cSrcweir // Slaves sind untereinander im Kreis verkettet 1522cdf0e10cSrcweir if (pSlaveSlot->GetNextSlot() == pFirstSlave) 1523cdf0e10cSrcweir break; 1524cdf0e10cSrcweir } 1525cdf0e10cSrcweir } 1526cdf0e10cSrcweir 1527cdf0e10cSrcweir if ( bInsert && bSameMethod ) 1528cdf0e10cSrcweir { 1529cdf0e10cSrcweir const SfxFoundCache_Impl *pFoundCache = new SfxFoundCache_Impl( 1530cdf0e10cSrcweir pSibling->GetSlotId(), pSibling->GetWhich(rPool), 1531cdf0e10cSrcweir pSibling, pSiblingCache ); 1532cdf0e10cSrcweir 1533cdf0e10cSrcweir rFound.Insert( pFoundCache ); 1534cdf0e10cSrcweir } 1535cdf0e10cSrcweir 1536cdf0e10cSrcweir pSibling = pSibling->GetNextSlot(); 1537cdf0e10cSrcweir } 1538cdf0e10cSrcweir 1539cdf0e10cSrcweir // aus den Ranges ein Set erzeugen 1540cdf0e10cSrcweir sal_uInt16 *pRanges = new sal_uInt16[rFound.Count() * 2 + 1]; 1541cdf0e10cSrcweir int j = 0; 1542cdf0e10cSrcweir sal_uInt16 i = 0; 1543cdf0e10cSrcweir while ( i < rFound.Count() ) 1544cdf0e10cSrcweir { 1545cdf0e10cSrcweir pRanges[j++] = rFound[i]->nWhichId; 1546cdf0e10cSrcweir // aufeinanderfolgende Zahlen 1547cdf0e10cSrcweir for ( ; i < rFound.Count()-1; ++i ) 1548cdf0e10cSrcweir if ( rFound[i]->nWhichId+1 != rFound[i+1]->nWhichId ) 1549cdf0e10cSrcweir break; 1550cdf0e10cSrcweir pRanges[j++] = rFound[i++]->nWhichId; 1551cdf0e10cSrcweir } 1552cdf0e10cSrcweir pRanges[j] = 0; // terminierende NULL 1553cdf0e10cSrcweir SfxItemSet *pSet = new SfxItemSet(rPool, pRanges); 1554cdf0e10cSrcweir delete [] pRanges; 1555cdf0e10cSrcweir DBG_PROFSTOP(SfxBindingsCreateSet); 1556cdf0e10cSrcweir return pSet; 1557cdf0e10cSrcweir } 1558cdf0e10cSrcweir 1559cdf0e10cSrcweir //-------------------------------------------------------------------- 1560cdf0e10cSrcweir 1561cdf0e10cSrcweir void SfxBindings::UpdateControllers_Impl 1562cdf0e10cSrcweir ( 1563cdf0e10cSrcweir const SfxInterface* pIF, // das diese Id momentan bedienende Interface 1564cdf0e10cSrcweir const SfxFoundCache_Impl* pFound, // Cache, Slot, Which etc. 1565cdf0e10cSrcweir const SfxPoolItem* pItem, // item to send to controller 1566cdf0e10cSrcweir SfxItemState eState // state of item 1567cdf0e10cSrcweir ) 1568cdf0e10cSrcweir { 1569cdf0e10cSrcweir DBG_ASSERT( !pFound->pSlot || SFX_KIND_ENUM != pFound->pSlot->GetKind(), 1570cdf0e10cSrcweir "direct update of enum slot isn't allowed" ); 1571cdf0e10cSrcweir DBG_PROFSTART(SfxBindingsUpdateCtrl1); 1572cdf0e10cSrcweir 1573cdf0e10cSrcweir SfxStateCache* pCache = pFound->pCache; 1574cdf0e10cSrcweir const SfxSlot* pSlot = pFound->pSlot; 1575cdf0e10cSrcweir DBG_ASSERT( !pCache || !pSlot || pCache->GetId() == pSlot->GetSlotId(), "SID mismatch" ); 1576cdf0e10cSrcweir 1577cdf0e10cSrcweir // insofern gebunden, die Controller f"uer den Slot selbst updaten 1578cdf0e10cSrcweir if ( pCache && pCache->IsControllerDirty() ) 1579cdf0e10cSrcweir { 1580cdf0e10cSrcweir if ( SFX_ITEM_DONTCARE == eState ) 1581cdf0e10cSrcweir { 1582cdf0e10cSrcweir // uneindeuting 1583cdf0e10cSrcweir pCache->SetState( SFX_ITEM_DONTCARE, (SfxPoolItem *)-1 ); 1584cdf0e10cSrcweir } 1585cdf0e10cSrcweir else if ( SFX_ITEM_DEFAULT == eState && 1586cdf0e10cSrcweir pFound->nWhichId > SFX_WHICH_MAX ) 1587cdf0e10cSrcweir { 1588cdf0e10cSrcweir // kein Status oder Default aber ohne Pool 1589cdf0e10cSrcweir SfxVoidItem aVoid(0); 1590cdf0e10cSrcweir pCache->SetState( SFX_ITEM_UNKNOWN, &aVoid ); 1591cdf0e10cSrcweir } 1592cdf0e10cSrcweir else if ( SFX_ITEM_DISABLED == eState ) 1593cdf0e10cSrcweir pCache->SetState(SFX_ITEM_DISABLED, 0); 1594cdf0e10cSrcweir else 1595cdf0e10cSrcweir pCache->SetState(SFX_ITEM_AVAILABLE, pItem); 1596cdf0e10cSrcweir } 1597cdf0e10cSrcweir 1598cdf0e10cSrcweir DBG_PROFSTOP(SfxBindingsUpdateCtrl1); 1599cdf0e10cSrcweir 1600cdf0e10cSrcweir // insofern vorhanden und gebunden, die Controller f"uer Slave-Slots 1601cdf0e10cSrcweir // (Enum-Werte) des Slots updaten 1602cdf0e10cSrcweir DBG_PROFSTART(SfxBindingsUpdateCtrl2); 1603cdf0e10cSrcweir DBG_ASSERT( !pSlot || 0 == pSlot->GetLinkedSlot() || !pItem || 1604cdf0e10cSrcweir pItem->ISA(SfxEnumItemInterface), 1605cdf0e10cSrcweir "master slot with non-enum-type found" ); 1606cdf0e10cSrcweir const SfxSlot *pFirstSlave = pSlot ? pSlot->GetLinkedSlot() : 0; 1607cdf0e10cSrcweir if ( pIF && pFirstSlave) 1608cdf0e10cSrcweir { 1609cdf0e10cSrcweir // Items auf EnumItem casten 1610cdf0e10cSrcweir const SfxEnumItemInterface *pEnumItem = 1611cdf0e10cSrcweir PTR_CAST(SfxEnumItemInterface,pItem); 1612cdf0e10cSrcweir if ( eState == SFX_ITEM_AVAILABLE && !pEnumItem ) 1613cdf0e10cSrcweir eState = SFX_ITEM_DONTCARE; 1614cdf0e10cSrcweir else 1615cdf0e10cSrcweir eState = SfxControllerItem::GetItemState( pEnumItem ); 1616cdf0e10cSrcweir 1617cdf0e10cSrcweir // "uber alle Slaves-Slots iterieren 1618cdf0e10cSrcweir for ( const SfxSlot *pSlave = pFirstSlave; pSlave; pSlave = pSlave->GetNextSlot() ) 1619cdf0e10cSrcweir { 1620cdf0e10cSrcweir DBG_ASSERT(pSlave, "Falsche SlaveSlot-Verkettung!"); 1621cdf0e10cSrcweir DBG_ASSERT(SFX_KIND_ENUM == pSlave->GetKind(),"non enum slaves aren't allowed"); 1622cdf0e10cSrcweir DBG_ASSERT(pSlave->GetMasterSlotId() == pSlot->GetSlotId(),"falscher MasterSlot!"); 1623cdf0e10cSrcweir 1624cdf0e10cSrcweir // ist die Funktion gebunden? 1625cdf0e10cSrcweir SfxStateCache *pEnumCache = GetStateCache( pSlave->GetSlotId() ); 1626cdf0e10cSrcweir if ( pEnumCache ) 1627cdf0e10cSrcweir { 1628cdf0e10cSrcweir pEnumCache->Invalidate(sal_False); 1629cdf0e10cSrcweir 1630cdf0e10cSrcweir HACK(CONTROL/SELECT Kram) 1631cdf0e10cSrcweir if ( eState == SFX_ITEM_DONTCARE && pFound->nWhichId == 10144 ) 1632cdf0e10cSrcweir { 1633cdf0e10cSrcweir SfxVoidItem aVoid(0); 1634cdf0e10cSrcweir pEnumCache->SetState( SFX_ITEM_UNKNOWN, &aVoid ); 1635cdf0e10cSrcweir 1636cdf0e10cSrcweir if (pSlave->GetNextSlot() == pFirstSlave) 1637cdf0e10cSrcweir break; 1638cdf0e10cSrcweir 1639cdf0e10cSrcweir continue; 1640cdf0e10cSrcweir } 1641cdf0e10cSrcweir 1642cdf0e10cSrcweir if ( SFX_ITEM_DISABLED == eState || !pEnumItem->IsEnabled( pSlave->GetSlotId()) ) 1643cdf0e10cSrcweir { 1644cdf0e10cSrcweir // disabled 1645cdf0e10cSrcweir pEnumCache->SetState(SFX_ITEM_DISABLED, 0); 1646cdf0e10cSrcweir } 1647cdf0e10cSrcweir else if ( SFX_ITEM_AVAILABLE == eState ) 1648cdf0e10cSrcweir { 1649cdf0e10cSrcweir // enum-Wert ermitteln 1650cdf0e10cSrcweir sal_uInt16 nValue = pEnumItem->GetEnumValue(); 1651cdf0e10cSrcweir SfxBoolItem aBool( pFound->nWhichId, pSlave->GetValue() == nValue ); 1652cdf0e10cSrcweir pEnumCache->SetState(SFX_ITEM_AVAILABLE, &aBool); 1653cdf0e10cSrcweir } 1654cdf0e10cSrcweir else 1655cdf0e10cSrcweir { 1656cdf0e10cSrcweir // uneindeuting 1657cdf0e10cSrcweir pEnumCache->SetState( SFX_ITEM_DONTCARE, (SfxPoolItem *)-1 ); 1658cdf0e10cSrcweir } 1659cdf0e10cSrcweir } 1660cdf0e10cSrcweir 1661cdf0e10cSrcweir if (pSlave->GetNextSlot() == pFirstSlave) 1662cdf0e10cSrcweir break; 1663cdf0e10cSrcweir } 1664cdf0e10cSrcweir } 1665cdf0e10cSrcweir 1666cdf0e10cSrcweir DBG_PROFSTOP(SfxBindingsUpdateCtrl2); 1667cdf0e10cSrcweir } 1668cdf0e10cSrcweir 1669cdf0e10cSrcweir 1670cdf0e10cSrcweir //-------------------------------------------------------------------- 1671cdf0e10cSrcweir 1672cdf0e10cSrcweir IMPL_LINK( SfxBindings, NextJob_Impl, Timer *, pTimer ) 1673cdf0e10cSrcweir { 1674cdf0e10cSrcweir #ifdef DBG_UTIL 1675cdf0e10cSrcweir // on Windows very often C++ Exceptions (GPF etc.) are caught by MSVCRT or another MS library 1676cdf0e10cSrcweir // try to get them here 1677cdf0e10cSrcweir try 1678cdf0e10cSrcweir { 1679cdf0e10cSrcweir #endif 1680cdf0e10cSrcweir const unsigned MAX_INPUT_DELAY = 200; 1681cdf0e10cSrcweir 1682cdf0e10cSrcweir DBG_MEMTEST(); 1683cdf0e10cSrcweir DBG_ASSERT( pImp->pCaches != 0, "SfxBindings not initialized" ); 1684cdf0e10cSrcweir 1685cdf0e10cSrcweir DBG_PROFSTART(SfxBindingsNextJob_Impl0); 1686cdf0e10cSrcweir 1687cdf0e10cSrcweir if ( Application::GetLastInputInterval() < MAX_INPUT_DELAY && pTimer ) 1688cdf0e10cSrcweir { 1689cdf0e10cSrcweir pImp->aTimer.SetTimeout(TIMEOUT_UPDATING); 1690cdf0e10cSrcweir return sal_True; 1691cdf0e10cSrcweir } 1692cdf0e10cSrcweir 1693cdf0e10cSrcweir SfxApplication *pSfxApp = SFX_APP(); 1694cdf0e10cSrcweir 1695cdf0e10cSrcweir if( pDispatcher ) 1696cdf0e10cSrcweir pDispatcher->Update_Impl(); 1697cdf0e10cSrcweir 1698cdf0e10cSrcweir // modifying the SfxObjectInterface-stack without SfxBindings => nothing to do 1699cdf0e10cSrcweir SfxViewFrame* pFrame = pDispatcher->GetFrame(); 1700cdf0e10cSrcweir //<!--Modified by PengYunQuan for Validity Cell Range Picker 1701cdf0e10cSrcweir //if ( (pFrame && pFrame->GetObjectShell()->IsInModalMode()) || pSfxApp->IsDowning() || !pImp->pCaches->Count() ) 1702cdf0e10cSrcweir if ( (pFrame && !pFrame->GetObjectShell()->AcceptStateUpdate()) || pSfxApp->IsDowning() || !pImp->pCaches->Count() ) 1703cdf0e10cSrcweir //-->Modified by PengYunQuan for Validity Cell Range Picker 1704cdf0e10cSrcweir { 1705cdf0e10cSrcweir DBG_PROFSTOP(SfxBindingsNextJob_Impl0); 1706cdf0e10cSrcweir return sal_True; 1707cdf0e10cSrcweir } 1708cdf0e10cSrcweir if ( !pDispatcher || !pDispatcher->IsFlushed() ) 1709cdf0e10cSrcweir { 1710cdf0e10cSrcweir DBG_PROFSTOP(SfxBindingsNextJob_Impl0); 1711cdf0e10cSrcweir return sal_True; 1712cdf0e10cSrcweir } 1713cdf0e10cSrcweir 1714cdf0e10cSrcweir // gfs. alle Server aktualisieren / geschieht in eigener Zeitscheibe 1715cdf0e10cSrcweir if ( pImp->bMsgDirty ) 1716cdf0e10cSrcweir { 1717cdf0e10cSrcweir UpdateSlotServer_Impl(); 1718cdf0e10cSrcweir DBG_PROFSTOP(SfxBindingsNextJob_Impl0); 1719cdf0e10cSrcweir return sal_False; 1720cdf0e10cSrcweir } 1721cdf0e10cSrcweir 1722cdf0e10cSrcweir DBG_PROFSTOP(SfxBindingsNextJob_Impl0); 1723cdf0e10cSrcweir DBG_PROFSTART(SfxBindingsNextJob_Impl); 1724cdf0e10cSrcweir pImp->bAllDirty = sal_False; 1725cdf0e10cSrcweir pImp->aTimer.SetTimeout(TIMEOUT_UPDATING); 1726cdf0e10cSrcweir 1727cdf0e10cSrcweir // at least 10 loops and further if more jobs are available but no input 1728cdf0e10cSrcweir bool bPreEmptive = pTimer && !pSfxApp->Get_Impl()->nInReschedule; 1729cdf0e10cSrcweir sal_uInt16 nLoops = 10; 1730cdf0e10cSrcweir pImp->bInNextJob = sal_True; 1731cdf0e10cSrcweir const sal_uInt16 nCount = pImp->pCaches->Count(); 1732cdf0e10cSrcweir while ( pImp->nMsgPos < nCount ) 1733cdf0e10cSrcweir { 1734cdf0e10cSrcweir // iterate through the bound functions 1735cdf0e10cSrcweir sal_Bool bJobDone = sal_False; 1736cdf0e10cSrcweir while ( !bJobDone ) 1737cdf0e10cSrcweir { 1738cdf0e10cSrcweir SfxStateCache* pCache = (*pImp->pCaches)[pImp->nMsgPos]; 1739cdf0e10cSrcweir DBG_ASSERT( pCache, "invalid SfxStateCache-position in job queue" ); 1740cdf0e10cSrcweir sal_Bool bWasDirty = pCache->IsControllerDirty(); 1741cdf0e10cSrcweir if ( bWasDirty ) 1742cdf0e10cSrcweir { 1743cdf0e10cSrcweir /* 1744cdf0e10cSrcweir sal_Bool bSkip = sal_False; 1745cdf0e10cSrcweir if ( pImp->bFirstRound ) 1746cdf0e10cSrcweir { 1747cdf0e10cSrcweir // Falls beim Update eine Shell vorgezogen werden soll, 1748cdf0e10cSrcweir // kommt in einer ersten Update-Runde nur diese dran 1749cdf0e10cSrcweir const SfxSlotServer *pMsgServer = 1750cdf0e10cSrcweir pCache->GetSlotServer(*pDispatcher, pImp->xProv); 1751cdf0e10cSrcweir if ( pMsgServer && 1752cdf0e10cSrcweir pMsgServer->GetShellLevel() != pImp->nFirstShell ) 1753cdf0e10cSrcweir bSkip = sal_True; 1754cdf0e10cSrcweir } 1755cdf0e10cSrcweir 1756cdf0e10cSrcweir if ( !bSkip ) 1757cdf0e10cSrcweir { 1758cdf0e10cSrcweir */ 1759cdf0e10cSrcweir Update_Impl( pCache ); 1760cdf0e10cSrcweir DBG_ASSERT( nCount == pImp->pCaches->Count(), 1761cdf0e10cSrcweir "Reschedule in StateChanged => buff" ); 1762cdf0e10cSrcweir // } 1763cdf0e10cSrcweir } 1764cdf0e10cSrcweir 1765cdf0e10cSrcweir // skip to next function binding 1766cdf0e10cSrcweir ++pImp->nMsgPos; 1767cdf0e10cSrcweir 1768cdf0e10cSrcweir // keep job if it is not completed, but any input is available 1769cdf0e10cSrcweir bJobDone = pImp->nMsgPos >= nCount; 1770cdf0e10cSrcweir if ( bJobDone && pImp->bFirstRound ) 1771cdf0e10cSrcweir { 1772cdf0e10cSrcweir // Update der bevorzugten Shell ist gelaufen, nun d"urfen 1773cdf0e10cSrcweir // auch die anderen 1774cdf0e10cSrcweir bJobDone = sal_False; 1775cdf0e10cSrcweir pImp->bFirstRound = sal_False; 1776cdf0e10cSrcweir pImp->nMsgPos = 0; 1777cdf0e10cSrcweir } 1778cdf0e10cSrcweir 1779cdf0e10cSrcweir if ( bWasDirty && !bJobDone && bPreEmptive && (--nLoops == 0) ) 1780cdf0e10cSrcweir { 1781cdf0e10cSrcweir DBG_PROFSTOP(SfxBindingsNextJob_Impl); 1782cdf0e10cSrcweir pImp->bInNextJob = sal_False; 1783cdf0e10cSrcweir return sal_False; 1784cdf0e10cSrcweir } 1785cdf0e10cSrcweir } 1786cdf0e10cSrcweir } 1787cdf0e10cSrcweir 1788cdf0e10cSrcweir pImp->nMsgPos = 0; 1789cdf0e10cSrcweir 1790cdf0e10cSrcweir // check for volatile slots 1791cdf0e10cSrcweir bool bVolatileSlotsPresent = false; 1792cdf0e10cSrcweir for ( sal_uInt16 n = 0; n < nCount; ++n ) 1793cdf0e10cSrcweir { 1794cdf0e10cSrcweir SfxStateCache* pCache = (*pImp->pCaches)[n]; 1795cdf0e10cSrcweir const SfxSlotServer *pSlotServer = pCache->GetSlotServer(*pDispatcher, pImp->xProv); 1796cdf0e10cSrcweir if ( pSlotServer && pSlotServer->GetSlot()->IsMode(SFX_SLOT_VOLATILE) ) 1797cdf0e10cSrcweir { 1798cdf0e10cSrcweir pCache->Invalidate(sal_False); 1799cdf0e10cSrcweir bVolatileSlotsPresent = true; 1800cdf0e10cSrcweir } 1801cdf0e10cSrcweir } 1802cdf0e10cSrcweir 1803cdf0e10cSrcweir if (bVolatileSlotsPresent) 1804cdf0e10cSrcweir pImp->aTimer.SetTimeout(TIMEOUT_IDLE); 1805cdf0e10cSrcweir else 1806cdf0e10cSrcweir pImp->aTimer.Stop(); 1807cdf0e10cSrcweir 1808cdf0e10cSrcweir // Update-Runde ist beendet 1809cdf0e10cSrcweir pImp->bInNextJob = sal_False; 1810cdf0e10cSrcweir Broadcast(SfxSimpleHint(SFX_HINT_UPDATEDONE)); 1811cdf0e10cSrcweir DBG_PROFSTOP(SfxBindingsNextJob_Impl); 1812cdf0e10cSrcweir return sal_True; 1813cdf0e10cSrcweir #ifdef DBG_UTIL 1814cdf0e10cSrcweir } 1815cdf0e10cSrcweir catch (...) 1816cdf0e10cSrcweir { 1817cdf0e10cSrcweir DBG_ERROR("C++ exception caught!"); 1818cdf0e10cSrcweir pImp->bInNextJob = sal_False; 1819cdf0e10cSrcweir } 1820cdf0e10cSrcweir 1821cdf0e10cSrcweir return sal_False; 1822cdf0e10cSrcweir #endif 1823cdf0e10cSrcweir } 1824cdf0e10cSrcweir 1825cdf0e10cSrcweir //-------------------------------------------------------------------- 1826cdf0e10cSrcweir 1827cdf0e10cSrcweir sal_uInt16 SfxBindings::EnterRegistrations(const char *pFile, int nLine) 1828cdf0e10cSrcweir { 1829cdf0e10cSrcweir (void)pFile; 1830cdf0e10cSrcweir (void)nLine; 1831cdf0e10cSrcweir DBG_MEMTEST(); 1832cdf0e10cSrcweir #ifdef DBG_UTIL 1833cdf0e10cSrcweir ByteString aMsg; 1834cdf0e10cSrcweir aMsg.Fill( Min(nRegLevel, sal_uInt16(8) ) ); 1835cdf0e10cSrcweir aMsg += "this = "; 1836cdf0e10cSrcweir aMsg += ByteString::CreateFromInt32((long)this); 1837cdf0e10cSrcweir aMsg += " Level = "; 1838cdf0e10cSrcweir aMsg += ByteString::CreateFromInt32(nRegLevel); 1839cdf0e10cSrcweir aMsg += " SfxBindings::EnterRegistrations "; 1840cdf0e10cSrcweir if(pFile) { 1841cdf0e10cSrcweir aMsg += "File: "; 1842cdf0e10cSrcweir aMsg += pFile; 1843cdf0e10cSrcweir aMsg += " Line: "; 1844cdf0e10cSrcweir aMsg += ByteString::CreateFromInt32(nLine); 1845cdf0e10cSrcweir } 1846cdf0e10cSrcweir // FILE* pLog = fopen( "c:\\bindings.log", "a+w" ); 1847cdf0e10cSrcweir // fwrite( aMsg.GetBuffer(), 1, aMsg.Len(), pLog ); 1848cdf0e10cSrcweir // fclose( pLog ); 1849cdf0e10cSrcweir DbgTrace( aMsg.GetBuffer() ); 1850cdf0e10cSrcweir #endif 1851cdf0e10cSrcweir 1852cdf0e10cSrcweir // Wenn Bindings gelockt werden, auch SubBindings locken 1853cdf0e10cSrcweir if ( pImp->pSubBindings ) 1854cdf0e10cSrcweir { 1855cdf0e10cSrcweir pImp->pSubBindings->ENTERREGISTRATIONS(); 1856cdf0e10cSrcweir 1857cdf0e10cSrcweir // Dieses EnterRegistrations ist f"ur die SubBindings kein "echtes" 1858cdf0e10cSrcweir pImp->pSubBindings->pImp->nOwnRegLevel--; 1859cdf0e10cSrcweir 1860cdf0e10cSrcweir // Bindings synchronisieren 1861cdf0e10cSrcweir pImp->pSubBindings->nRegLevel = nRegLevel + pImp->pSubBindings->pImp->nOwnRegLevel + 1; 1862cdf0e10cSrcweir } 1863cdf0e10cSrcweir 1864cdf0e10cSrcweir pImp->nOwnRegLevel++; 1865cdf0e10cSrcweir 1866cdf0e10cSrcweir // check if this is the outer most level 1867cdf0e10cSrcweir if ( ++nRegLevel == 1 ) 1868cdf0e10cSrcweir { 1869cdf0e10cSrcweir // stop background-processing 1870cdf0e10cSrcweir pImp->aTimer.Stop(); 1871cdf0e10cSrcweir 1872cdf0e10cSrcweir // flush the cache 1873cdf0e10cSrcweir pImp->nCachedFunc1 = 0; 1874cdf0e10cSrcweir pImp->nCachedFunc2 = 0; 1875cdf0e10cSrcweir 1876cdf0e10cSrcweir // merken, ob ganze Caches verschwunden sind 1877cdf0e10cSrcweir pImp->bCtrlReleased = sal_False; 1878cdf0e10cSrcweir } 1879cdf0e10cSrcweir 1880cdf0e10cSrcweir return nRegLevel; 1881cdf0e10cSrcweir } 1882cdf0e10cSrcweir //-------------------------------------------------------------------- 1883cdf0e10cSrcweir 1884cdf0e10cSrcweir void SfxBindings::LeaveRegistrations( sal_uInt16 nLevel, const char *pFile, int nLine ) 1885cdf0e10cSrcweir { 1886cdf0e10cSrcweir (void)nLevel; // unused variable 1887cdf0e10cSrcweir (void)pFile; 1888cdf0e10cSrcweir (void)nLine; 1889cdf0e10cSrcweir DBG_MEMTEST(); 1890cdf0e10cSrcweir DBG_ASSERT( nRegLevel, "Leave without Enter" ); 1891cdf0e10cSrcweir DBG_ASSERT( nLevel == USHRT_MAX || nLevel == nRegLevel, "wrong Leave" ); 1892cdf0e10cSrcweir 1893cdf0e10cSrcweir // Nur wenn die SubBindings noch von den SuperBindings gelockt sind, diesen Lock entfernen 1894cdf0e10cSrcweir // ( d.h. wenn es mehr Locks als "echte" Locks dort gibt ) 1895cdf0e10cSrcweir if ( pImp->pSubBindings && pImp->pSubBindings->nRegLevel > pImp->pSubBindings->pImp->nOwnRegLevel ) 1896cdf0e10cSrcweir { 1897cdf0e10cSrcweir // Bindings synchronisieren 1898cdf0e10cSrcweir pImp->pSubBindings->nRegLevel = nRegLevel + pImp->pSubBindings->pImp->nOwnRegLevel; 1899cdf0e10cSrcweir 1900cdf0e10cSrcweir // Dieses LeaveRegistrations ist f"ur die SubBindings kein "echtes" 1901cdf0e10cSrcweir pImp->pSubBindings->pImp->nOwnRegLevel++; 1902cdf0e10cSrcweir pImp->pSubBindings->LEAVEREGISTRATIONS(); 1903cdf0e10cSrcweir } 1904cdf0e10cSrcweir 1905cdf0e10cSrcweir pImp->nOwnRegLevel--; 1906cdf0e10cSrcweir 1907cdf0e10cSrcweir // check if this is the outer most level 1908cdf0e10cSrcweir if ( --nRegLevel == 0 && !SFX_APP()->IsDowning() ) 1909cdf0e10cSrcweir { 1910cdf0e10cSrcweir if ( pImp->bContextChanged ) 1911cdf0e10cSrcweir { 1912cdf0e10cSrcweir pImp->bContextChanged = sal_False; 1913cdf0e10cSrcweir /* 1914cdf0e10cSrcweir ::com::sun::star::uno::Reference < ::com::sun::star::frame::XFrame > xFrame 1915cdf0e10cSrcweir ( pDispatcher->GetFrame()->GetFrame().GetFrameInterface(), UNO_QUERY ); 1916cdf0e10cSrcweir if ( xFrame.is() ) 1917cdf0e10cSrcweir xFrame->contextChanged();*/ 1918cdf0e10cSrcweir } 1919cdf0e10cSrcweir 1920cdf0e10cSrcweir #ifndef slow 1921cdf0e10cSrcweir SfxViewFrame* pFrame = pDispatcher->GetFrame(); 1922cdf0e10cSrcweir 1923cdf0e10cSrcweir // ggf unbenutzte Caches entfernen bzw. PlugInInfo aufbereiten 1924cdf0e10cSrcweir if ( pImp->bCtrlReleased ) 1925cdf0e10cSrcweir { 1926cdf0e10cSrcweir for ( sal_uInt16 nCache = pImp->pCaches->Count(); nCache > 0; --nCache ) 1927cdf0e10cSrcweir { 1928cdf0e10cSrcweir // Cache via ::com::sun::star::sdbcx::Index besorgen 1929cdf0e10cSrcweir SfxStateCache *pCache = pImp->pCaches->GetObject(nCache-1); 1930cdf0e10cSrcweir 1931cdf0e10cSrcweir // kein Controller mehr interessiert 1932cdf0e10cSrcweir if ( pCache->GetItemLink() == 0 && !pCache->GetInternalController() ) 1933cdf0e10cSrcweir { 1934cdf0e10cSrcweir // Cache entfernen. Safety: first remove and then delete 1935cdf0e10cSrcweir SfxStateCache* pSfxStateCache = (*pImp->pCaches)[nCache-1]; 1936cdf0e10cSrcweir pImp->pCaches->Remove(nCache-1, 1); 1937cdf0e10cSrcweir delete pSfxStateCache; 1938cdf0e10cSrcweir } 1939cdf0e10cSrcweir else 1940cdf0e10cSrcweir { 1941cdf0e10cSrcweir // neue Controller mit den alten Items benachrichtigen 1942cdf0e10cSrcweir //!pCache->SetCachedState(); 1943cdf0e10cSrcweir } 1944cdf0e10cSrcweir } 1945cdf0e10cSrcweir } 1946cdf0e10cSrcweir #endif 1947cdf0e10cSrcweir // restart background-processing 1948cdf0e10cSrcweir pImp->nMsgPos = 0; 1949cdf0e10cSrcweir if ( !pFrame || !pFrame->GetObjectShell() ) 1950cdf0e10cSrcweir return; 1951cdf0e10cSrcweir if ( pImp->pCaches && pImp->pCaches->Count() ) 1952cdf0e10cSrcweir { 1953cdf0e10cSrcweir pImp->aTimer.Stop(); 1954cdf0e10cSrcweir pImp->aTimer.SetTimeout(TIMEOUT_FIRST); 1955cdf0e10cSrcweir pImp->aTimer.Start(); 1956cdf0e10cSrcweir // pImp->bFirstRound = sal_True; 1957cdf0e10cSrcweir } 1958cdf0e10cSrcweir } 1959cdf0e10cSrcweir 1960cdf0e10cSrcweir #ifdef DBG_UTIL 1961cdf0e10cSrcweir ByteString aMsg; 1962cdf0e10cSrcweir aMsg.Fill( Min(nRegLevel, sal_uInt16(8)) ); 1963cdf0e10cSrcweir aMsg += "this = "; 1964cdf0e10cSrcweir aMsg += ByteString::CreateFromInt32((long)this); 1965cdf0e10cSrcweir aMsg += " Level = "; 1966cdf0e10cSrcweir aMsg += ByteString::CreateFromInt32(nRegLevel); 1967cdf0e10cSrcweir aMsg += " SfxBindings::LeaveRegistrations "; 1968cdf0e10cSrcweir if(pFile) { 1969cdf0e10cSrcweir aMsg += "File: "; 1970cdf0e10cSrcweir aMsg += pFile; 1971cdf0e10cSrcweir aMsg += " Line: "; 1972cdf0e10cSrcweir aMsg += ByteString::CreateFromInt32(nLine); 1973cdf0e10cSrcweir } 1974cdf0e10cSrcweir // FILE* pLog = fopen( "c:\\bindings.log", "a+w" ); 1975cdf0e10cSrcweir // fwrite( aMsg.GetBuffer(), 1, aMsg.Len(), pLog ); 1976cdf0e10cSrcweir // fclose( pLog ); 1977cdf0e10cSrcweir DbgTrace( aMsg.GetBuffer() ); 1978cdf0e10cSrcweir #endif 1979cdf0e10cSrcweir } 1980cdf0e10cSrcweir 1981cdf0e10cSrcweir //-------------------------------------------------------------------- 1982cdf0e10cSrcweir 1983cdf0e10cSrcweir const SfxSlot* SfxBindings::GetSlot(sal_uInt16 nSlotId) 1984cdf0e10cSrcweir { 1985cdf0e10cSrcweir DBG_MEMTEST(); 1986cdf0e10cSrcweir DBG_ASSERT( pImp->pCaches != 0, "SfxBindings not initialized" ); 1987cdf0e10cSrcweir 1988cdf0e10cSrcweir // syncronisieren 1989cdf0e10cSrcweir pDispatcher->Flush(); 1990cdf0e10cSrcweir if ( pImp->bMsgDirty ) 1991cdf0e10cSrcweir UpdateSlotServer_Impl(); 1992cdf0e10cSrcweir 1993cdf0e10cSrcweir // get the cache for the specified function; return if not bound 1994cdf0e10cSrcweir SfxStateCache* pCache = GetStateCache(nSlotId); 1995cdf0e10cSrcweir return pCache && pCache->GetSlotServer(*pDispatcher, pImp->xProv)? 1996cdf0e10cSrcweir pCache->GetSlotServer(*pDispatcher, pImp->xProv)->GetSlot(): 0; 1997cdf0e10cSrcweir } 1998cdf0e10cSrcweir 1999cdf0e10cSrcweir //-------------------------------------------------------------------- 2000cdf0e10cSrcweir 2001cdf0e10cSrcweir void SfxBindings::SetDispatcher( SfxDispatcher *pDisp ) 2002cdf0e10cSrcweir { 2003cdf0e10cSrcweir SfxDispatcher *pOldDispat = pDispatcher; 2004cdf0e10cSrcweir if ( pDisp != pDispatcher ) 2005cdf0e10cSrcweir { 2006cdf0e10cSrcweir if ( pOldDispat ) 2007cdf0e10cSrcweir { 2008cdf0e10cSrcweir SfxBindings* pBind = pOldDispat->GetBindings(); 2009cdf0e10cSrcweir while ( pBind ) 2010cdf0e10cSrcweir { 2011cdf0e10cSrcweir if ( pBind->pImp->pSubBindings == this && pBind->pDispatcher != pDisp ) 2012cdf0e10cSrcweir pBind->SetSubBindings_Impl( NULL ); 2013cdf0e10cSrcweir pBind = pBind->pImp->pSubBindings; 2014cdf0e10cSrcweir } 2015cdf0e10cSrcweir } 2016cdf0e10cSrcweir 2017cdf0e10cSrcweir pDispatcher = pDisp; 2018cdf0e10cSrcweir 2019cdf0e10cSrcweir ::com::sun::star::uno::Reference < ::com::sun::star::frame::XDispatchProvider > xProv; 2020cdf0e10cSrcweir if ( pDisp ) 2021cdf0e10cSrcweir xProv = ::com::sun::star::uno::Reference < ::com::sun::star::frame::XDispatchProvider > 2022cdf0e10cSrcweir ( pDisp->GetFrame()->GetFrame().GetFrameInterface(), UNO_QUERY ); 2023cdf0e10cSrcweir 2024cdf0e10cSrcweir SetDispatchProvider_Impl( xProv ); 2025cdf0e10cSrcweir InvalidateAll( sal_True ); 2026cdf0e10cSrcweir InvalidateUnoControllers_Impl(); 2027cdf0e10cSrcweir 2028cdf0e10cSrcweir if ( pDispatcher && !pOldDispat ) 2029cdf0e10cSrcweir { 2030cdf0e10cSrcweir if ( pImp->pSubBindings && pImp->pSubBindings->pDispatcher != pOldDispat ) 2031cdf0e10cSrcweir { 2032cdf0e10cSrcweir DBG_ERROR( "SubBindings vor Aktivieren schon gesetzt!" ); 2033cdf0e10cSrcweir pImp->pSubBindings->ENTERREGISTRATIONS(); 2034cdf0e10cSrcweir } 2035cdf0e10cSrcweir LEAVEREGISTRATIONS(); 2036cdf0e10cSrcweir } 2037cdf0e10cSrcweir else if( !pDispatcher ) 2038cdf0e10cSrcweir { 2039cdf0e10cSrcweir ENTERREGISTRATIONS(); 2040cdf0e10cSrcweir if ( pImp->pSubBindings && pImp->pSubBindings->pDispatcher != pOldDispat ) 2041cdf0e10cSrcweir { 2042cdf0e10cSrcweir DBG_ERROR( "SubBindings im Deaktivieren immer noch gesetzt!" ); 2043cdf0e10cSrcweir pImp->pSubBindings->LEAVEREGISTRATIONS(); 2044cdf0e10cSrcweir } 2045cdf0e10cSrcweir } 2046cdf0e10cSrcweir 2047cdf0e10cSrcweir Broadcast( SfxSimpleHint( SFX_HINT_DATACHANGED ) ); 2048cdf0e10cSrcweir 2049cdf0e10cSrcweir if ( pDisp ) 2050cdf0e10cSrcweir { 2051cdf0e10cSrcweir SfxBindings* pBind = pDisp->GetBindings(); 2052cdf0e10cSrcweir while ( pBind && pBind != this ) 2053cdf0e10cSrcweir { 2054cdf0e10cSrcweir if ( !pBind->pImp->pSubBindings ) 2055cdf0e10cSrcweir { 2056cdf0e10cSrcweir pBind->SetSubBindings_Impl( this ); 2057cdf0e10cSrcweir break; 2058cdf0e10cSrcweir } 2059cdf0e10cSrcweir 2060cdf0e10cSrcweir pBind = pBind->pImp->pSubBindings; 2061cdf0e10cSrcweir } 2062cdf0e10cSrcweir } 2063cdf0e10cSrcweir } 2064cdf0e10cSrcweir } 2065cdf0e10cSrcweir 2066cdf0e10cSrcweir //-------------------------------------------------------------------- 2067cdf0e10cSrcweir 2068cdf0e10cSrcweir void SfxBindings::ClearCache_Impl( sal_uInt16 nSlotId ) 2069cdf0e10cSrcweir { 2070cdf0e10cSrcweir GetStateCache(nSlotId)->ClearCache(); 2071cdf0e10cSrcweir } 2072cdf0e10cSrcweir 2073cdf0e10cSrcweir //-------------------------------------------------------------------- 2074cdf0e10cSrcweir void SfxBindings::StartUpdate_Impl( sal_Bool bComplete ) 2075cdf0e10cSrcweir { 2076cdf0e10cSrcweir if ( pImp->pSubBindings ) 2077cdf0e10cSrcweir pImp->pSubBindings->StartUpdate_Impl( bComplete ); 2078cdf0e10cSrcweir 2079cdf0e10cSrcweir if ( !bComplete ) 2080cdf0e10cSrcweir // Update darf unterbrochen werden 2081cdf0e10cSrcweir NextJob_Impl(&pImp->aTimer); 2082cdf0e10cSrcweir else 2083cdf0e10cSrcweir // alle Slots am St"uck updaten 2084cdf0e10cSrcweir NextJob_Impl(0); 2085cdf0e10cSrcweir } 2086cdf0e10cSrcweir 2087cdf0e10cSrcweir //------------------------------------------------------------------------- 2088cdf0e10cSrcweir 2089cdf0e10cSrcweir SfxItemState SfxBindings::QueryState( sal_uInt16 nSlot, SfxPoolItem* &rpState ) 2090cdf0e10cSrcweir { 2091cdf0e10cSrcweir ::com::sun::star::uno::Reference< ::com::sun::star::frame::XDispatch > xDisp; 2092cdf0e10cSrcweir SfxStateCache *pCache = GetStateCache( nSlot ); 2093cdf0e10cSrcweir if ( pCache ) 2094cdf0e10cSrcweir xDisp = pCache->GetDispatch(); 2095cdf0e10cSrcweir if ( xDisp.is() || !pCache ) 2096cdf0e10cSrcweir { 2097cdf0e10cSrcweir const SfxSlot* pSlot = SfxSlotPool::GetSlotPool( pDispatcher->GetFrame() ).GetSlot( nSlot ); 2098cdf0e10cSrcweir if ( !pSlot || !pSlot->pUnoName ) 2099cdf0e10cSrcweir return SFX_ITEM_DISABLED; 2100cdf0e10cSrcweir 2101cdf0e10cSrcweir ::com::sun::star::util::URL aURL; 2102cdf0e10cSrcweir ::rtl::OUString aCmd( DEFINE_CONST_UNICODE(".uno:")); 2103cdf0e10cSrcweir aURL.Protocol = aCmd; 2104cdf0e10cSrcweir aURL.Path = ::rtl::OUString::createFromAscii(pSlot->GetUnoName()); 2105cdf0e10cSrcweir aCmd += aURL.Path; 2106cdf0e10cSrcweir aURL.Complete = aCmd; 2107cdf0e10cSrcweir aURL.Main = aCmd; 2108cdf0e10cSrcweir 2109cdf0e10cSrcweir if ( !xDisp.is() ) 2110cdf0e10cSrcweir xDisp = pImp->xProv->queryDispatch( aURL, ::rtl::OUString(), 0 ); 2111cdf0e10cSrcweir 2112cdf0e10cSrcweir if ( xDisp.is() ) 2113cdf0e10cSrcweir { 2114cdf0e10cSrcweir ::com::sun::star::uno::Reference< ::com::sun::star::lang::XUnoTunnel > xTunnel( xDisp, ::com::sun::star::uno::UNO_QUERY ); 2115cdf0e10cSrcweir SfxOfficeDispatch* pDisp = NULL; 2116cdf0e10cSrcweir if ( xTunnel.is() ) 2117cdf0e10cSrcweir { 2118cdf0e10cSrcweir sal_Int64 nImplementation = xTunnel->getSomething(SfxOfficeDispatch::impl_getStaticIdentifier()); 2119cdf0e10cSrcweir pDisp = reinterpret_cast< SfxOfficeDispatch* >( sal::static_int_cast< sal_IntPtr >( nImplementation )); 2120cdf0e10cSrcweir } 2121cdf0e10cSrcweir 2122cdf0e10cSrcweir if ( !pDisp ) 2123cdf0e10cSrcweir { 2124cdf0e10cSrcweir sal_Bool bDeleteCache = sal_False; 2125cdf0e10cSrcweir if ( !pCache ) 2126cdf0e10cSrcweir { 2127cdf0e10cSrcweir pCache = new SfxStateCache( nSlot ); 2128cdf0e10cSrcweir pCache->GetSlotServer( *GetDispatcher_Impl(), pImp->xProv ); 2129cdf0e10cSrcweir bDeleteCache = sal_True; 2130cdf0e10cSrcweir } 2131cdf0e10cSrcweir 2132cdf0e10cSrcweir SfxItemState eState = SFX_ITEM_SET; 2133cdf0e10cSrcweir SfxPoolItem *pItem=NULL; 2134cdf0e10cSrcweir BindDispatch_Impl *pBind = new BindDispatch_Impl( xDisp, aURL, pCache, pSlot ); 2135cdf0e10cSrcweir pBind->acquire(); 2136cdf0e10cSrcweir xDisp->addStatusListener( pBind, aURL ); 2137cdf0e10cSrcweir if ( !pBind->GetStatus().IsEnabled ) 2138cdf0e10cSrcweir { 2139cdf0e10cSrcweir eState = SFX_ITEM_DISABLED; 2140cdf0e10cSrcweir } 2141cdf0e10cSrcweir else 2142cdf0e10cSrcweir { 2143cdf0e10cSrcweir ::com::sun::star::uno::Any aAny = pBind->GetStatus().State; 2144cdf0e10cSrcweir ::com::sun::star::uno::Type pType = aAny.getValueType(); 2145cdf0e10cSrcweir 2146cdf0e10cSrcweir if ( pType == ::getBooleanCppuType() ) 2147cdf0e10cSrcweir { 2148cdf0e10cSrcweir sal_Bool bTemp = false; 2149cdf0e10cSrcweir aAny >>= bTemp ; 2150cdf0e10cSrcweir pItem = new SfxBoolItem( nSlot, bTemp ); 2151cdf0e10cSrcweir } 2152cdf0e10cSrcweir else if ( pType == ::getCppuType((const sal_uInt16*)0) ) 2153cdf0e10cSrcweir { 2154cdf0e10cSrcweir sal_uInt16 nTemp = 0; 2155cdf0e10cSrcweir aAny >>= nTemp ; 2156cdf0e10cSrcweir pItem = new SfxUInt16Item( nSlot, nTemp ); 2157cdf0e10cSrcweir } 2158cdf0e10cSrcweir else if ( pType == ::getCppuType((const sal_uInt32*)0) ) 2159cdf0e10cSrcweir { 2160cdf0e10cSrcweir sal_uInt32 nTemp = 0; 2161cdf0e10cSrcweir aAny >>= nTemp ; 2162cdf0e10cSrcweir pItem = new SfxUInt32Item( nSlot, nTemp ); 2163cdf0e10cSrcweir } 2164cdf0e10cSrcweir else if ( pType == ::getCppuType((const ::rtl::OUString*)0) ) 2165cdf0e10cSrcweir { 2166cdf0e10cSrcweir ::rtl::OUString sTemp ; 2167cdf0e10cSrcweir aAny >>= sTemp ; 2168cdf0e10cSrcweir pItem = new SfxStringItem( nSlot, sTemp ); 2169cdf0e10cSrcweir } 2170cdf0e10cSrcweir else 2171cdf0e10cSrcweir pItem = new SfxVoidItem( nSlot ); 2172cdf0e10cSrcweir } 2173cdf0e10cSrcweir 2174cdf0e10cSrcweir xDisp->removeStatusListener( pBind, aURL ); 2175cdf0e10cSrcweir pBind->Release(); 2176cdf0e10cSrcweir rpState = pItem; 2177cdf0e10cSrcweir if ( bDeleteCache ) 2178cdf0e10cSrcweir DELETEZ( pCache ); 2179cdf0e10cSrcweir return eState; 2180cdf0e10cSrcweir } 2181cdf0e10cSrcweir } 2182cdf0e10cSrcweir } 2183cdf0e10cSrcweir 2184cdf0e10cSrcweir // Dann am Dispatcher testen; da die von dort zur"uckgegebenen Items immer 2185cdf0e10cSrcweir // DELETE_ON_IDLE sind, mu\s eine Kopie davon gezogen werden, um einen 2186cdf0e10cSrcweir // Eigent"umer"ubergang zu erm"oglichen 2187cdf0e10cSrcweir const SfxPoolItem *pItem = NULL; 2188cdf0e10cSrcweir SfxItemState eState = pDispatcher->QueryState( nSlot, pItem ); 2189cdf0e10cSrcweir if ( eState == SFX_ITEM_SET ) 2190cdf0e10cSrcweir { 2191cdf0e10cSrcweir DBG_ASSERT( pItem, "SFX_ITEM_SET aber kein Item!" ); 2192cdf0e10cSrcweir if ( pItem ) 2193cdf0e10cSrcweir rpState = pItem->Clone(); 2194cdf0e10cSrcweir } 2195cdf0e10cSrcweir else if ( eState == SFX_ITEM_AVAILABLE && pItem ) 2196cdf0e10cSrcweir { 2197cdf0e10cSrcweir rpState = pItem->Clone(); 2198cdf0e10cSrcweir } 2199cdf0e10cSrcweir 2200cdf0e10cSrcweir return eState; 2201cdf0e10cSrcweir } 2202cdf0e10cSrcweir 2203cdf0e10cSrcweir void SfxBindings::SetSubBindings_Impl( SfxBindings *pSub ) 2204cdf0e10cSrcweir { 2205cdf0e10cSrcweir if ( pImp->pSubBindings ) 2206cdf0e10cSrcweir { 2207cdf0e10cSrcweir pImp->pSubBindings->SetDispatchProvider_Impl( ::com::sun::star::uno::Reference< ::com::sun::star::frame::XDispatchProvider > () ); 2208cdf0e10cSrcweir pImp->pSubBindings->pImp->pSuperBindings = NULL; 2209cdf0e10cSrcweir } 2210cdf0e10cSrcweir 2211cdf0e10cSrcweir pImp->pSubBindings = pSub; 2212cdf0e10cSrcweir 2213cdf0e10cSrcweir if ( pSub ) 2214cdf0e10cSrcweir { 2215cdf0e10cSrcweir pImp->pSubBindings->SetDispatchProvider_Impl( pImp->xProv ); 2216cdf0e10cSrcweir pSub->pImp->pSuperBindings = this; 2217cdf0e10cSrcweir } 2218cdf0e10cSrcweir } 2219cdf0e10cSrcweir 2220cdf0e10cSrcweir SfxBindings* SfxBindings::GetSubBindings_Impl( sal_Bool bTop ) const 2221cdf0e10cSrcweir { 2222cdf0e10cSrcweir SfxBindings *pRet = pImp->pSubBindings; 2223cdf0e10cSrcweir if ( bTop ) 2224cdf0e10cSrcweir { 2225cdf0e10cSrcweir while ( pRet->pImp->pSubBindings ) 2226cdf0e10cSrcweir pRet = pRet->pImp->pSubBindings; 2227cdf0e10cSrcweir } 2228cdf0e10cSrcweir 2229cdf0e10cSrcweir return pRet; 2230cdf0e10cSrcweir } 2231cdf0e10cSrcweir 2232cdf0e10cSrcweir void SfxBindings::SetWorkWindow_Impl( SfxWorkWindow* pWork ) 2233cdf0e10cSrcweir { 2234cdf0e10cSrcweir pImp->pWorkWin = pWork; 2235cdf0e10cSrcweir } 2236cdf0e10cSrcweir 2237cdf0e10cSrcweir SfxWorkWindow* SfxBindings::GetWorkWindow_Impl() const 2238cdf0e10cSrcweir { 2239cdf0e10cSrcweir return pImp->pWorkWin; 2240cdf0e10cSrcweir } 2241cdf0e10cSrcweir 2242cdf0e10cSrcweir void SfxBindings::RegisterUnoController_Impl( SfxUnoControllerItem* pControl ) 2243cdf0e10cSrcweir { 2244cdf0e10cSrcweir if ( !pImp->pUnoCtrlArr ) 2245cdf0e10cSrcweir pImp->pUnoCtrlArr = new SfxUnoControllerArr_Impl; 2246cdf0e10cSrcweir pImp->pUnoCtrlArr->Insert( pControl, pImp->pUnoCtrlArr->Count() ); 2247cdf0e10cSrcweir } 2248cdf0e10cSrcweir 2249cdf0e10cSrcweir void SfxBindings::ReleaseUnoController_Impl( SfxUnoControllerItem* pControl ) 2250cdf0e10cSrcweir { 2251cdf0e10cSrcweir if ( pImp->pUnoCtrlArr ) 2252cdf0e10cSrcweir { 2253cdf0e10cSrcweir sal_uInt16 nPos = pImp->pUnoCtrlArr->GetPos( pControl ); 2254cdf0e10cSrcweir if ( nPos != 0xFFFF ) 2255cdf0e10cSrcweir { 2256cdf0e10cSrcweir pImp->pUnoCtrlArr->Remove( nPos ); 2257cdf0e10cSrcweir return; 2258cdf0e10cSrcweir } 2259cdf0e10cSrcweir } 2260cdf0e10cSrcweir 2261cdf0e10cSrcweir if ( pImp->pSubBindings ) 2262cdf0e10cSrcweir pImp->pSubBindings->ReleaseUnoController_Impl( pControl ); 2263cdf0e10cSrcweir } 2264cdf0e10cSrcweir 2265cdf0e10cSrcweir void SfxBindings::InvalidateUnoControllers_Impl() 2266cdf0e10cSrcweir { 2267cdf0e10cSrcweir if ( pImp->pUnoCtrlArr ) 2268cdf0e10cSrcweir { 2269cdf0e10cSrcweir sal_uInt16 nCount = pImp->pUnoCtrlArr->Count(); 2270cdf0e10cSrcweir for ( sal_uInt16 n=nCount; n>0; n-- ) 2271cdf0e10cSrcweir { 2272cdf0e10cSrcweir SfxUnoControllerItem *pCtrl = (*pImp->pUnoCtrlArr)[n-1]; 2273cdf0e10cSrcweir ::com::sun::star::uno::Reference< ::com::sun::star::frame::XStatusListener > xRef( (::cppu::OWeakObject*)pCtrl, ::com::sun::star::uno::UNO_QUERY ); 2274cdf0e10cSrcweir pCtrl->ReleaseDispatch(); 2275cdf0e10cSrcweir pCtrl->GetNewDispatch(); 2276cdf0e10cSrcweir } 2277cdf0e10cSrcweir } 2278cdf0e10cSrcweir 2279cdf0e10cSrcweir if ( pImp->pSubBindings ) 2280cdf0e10cSrcweir pImp->pSubBindings->InvalidateUnoControllers_Impl(); 2281cdf0e10cSrcweir } 2282cdf0e10cSrcweir 2283cdf0e10cSrcweir sal_Bool SfxBindings::IsInUpdate() const 2284cdf0e10cSrcweir { 2285cdf0e10cSrcweir sal_Bool bInUpdate = pImp->bInUpdate; 2286cdf0e10cSrcweir if ( !bInUpdate && pImp->pSubBindings ) 2287cdf0e10cSrcweir bInUpdate = pImp->pSubBindings->IsInUpdate(); 2288cdf0e10cSrcweir return bInUpdate; 2289cdf0e10cSrcweir } 2290cdf0e10cSrcweir 2291cdf0e10cSrcweir void SfxBindings::SetVisibleState( sal_uInt16 nId, sal_Bool bShow ) 2292cdf0e10cSrcweir { 2293cdf0e10cSrcweir ::com::sun::star::uno::Reference< ::com::sun::star::frame::XDispatch > xDisp; 2294cdf0e10cSrcweir SfxStateCache *pCache = GetStateCache( nId ); 2295cdf0e10cSrcweir if ( pCache ) 2296cdf0e10cSrcweir pCache->SetVisibleState( bShow ); 2297cdf0e10cSrcweir } 2298cdf0e10cSrcweir 2299cdf0e10cSrcweir void SfxBindings::SetActiveFrame( const ::com::sun::star::uno::Reference< ::com::sun::star::frame::XFrame > & rFrame ) 2300cdf0e10cSrcweir { 2301cdf0e10cSrcweir if ( rFrame.is() || !pDispatcher ) 2302cdf0e10cSrcweir SetDispatchProvider_Impl( ::com::sun::star::uno::Reference< ::com::sun::star::frame::XDispatchProvider > ( rFrame, ::com::sun::star::uno::UNO_QUERY ) ); 2303cdf0e10cSrcweir else 2304cdf0e10cSrcweir SetDispatchProvider_Impl( ::com::sun::star::uno::Reference< ::com::sun::star::frame::XDispatchProvider > ( 2305cdf0e10cSrcweir pDispatcher->GetFrame()->GetFrame().GetFrameInterface(), ::com::sun::star::uno::UNO_QUERY ) ); 2306cdf0e10cSrcweir } 2307cdf0e10cSrcweir 2308cdf0e10cSrcweir const ::com::sun::star::uno::Reference< ::com::sun::star::frame::XFrame > SfxBindings::GetActiveFrame() const 2309cdf0e10cSrcweir { 2310cdf0e10cSrcweir const ::com::sun::star::uno::Reference< ::com::sun::star::frame::XFrame > xFrame( pImp->xProv, ::com::sun::star::uno::UNO_QUERY ); 2311cdf0e10cSrcweir if ( xFrame.is() || !pDispatcher ) 2312cdf0e10cSrcweir return xFrame; 2313cdf0e10cSrcweir else 2314cdf0e10cSrcweir return pDispatcher->GetFrame()->GetFrame().GetFrameInterface(); 2315cdf0e10cSrcweir } 2316cdf0e10cSrcweir 2317cdf0e10cSrcweir void SfxBindings::SetDispatchProvider_Impl( const ::com::sun::star::uno::Reference< ::com::sun::star::frame::XDispatchProvider > & rProv ) 2318cdf0e10cSrcweir { 2319cdf0e10cSrcweir sal_Bool bInvalidate = ( rProv != pImp->xProv ); 2320cdf0e10cSrcweir if ( bInvalidate ) 2321cdf0e10cSrcweir { 2322cdf0e10cSrcweir pImp->xProv = rProv; 2323cdf0e10cSrcweir InvalidateAll( sal_True ); 2324cdf0e10cSrcweir InvalidateUnoControllers_Impl(); 2325cdf0e10cSrcweir } 2326cdf0e10cSrcweir 2327cdf0e10cSrcweir if ( pImp->pSubBindings ) 2328cdf0e10cSrcweir pImp->pSubBindings->SetDispatchProvider_Impl( pImp->xProv ); 2329cdf0e10cSrcweir } 2330cdf0e10cSrcweir 2331cdf0e10cSrcweir const ::com::sun::star::uno::Reference< ::com::sun::star::frame::XDispatchProvider > & SfxBindings::GetDispatchProvider_Impl() const 2332cdf0e10cSrcweir { 2333cdf0e10cSrcweir return pImp->xProv; 2334cdf0e10cSrcweir } 2335cdf0e10cSrcweir 2336cdf0e10cSrcweir SystemWindow* SfxBindings::GetSystemWindow() const 2337cdf0e10cSrcweir { 2338cdf0e10cSrcweir SfxViewFrame *pFrame = pDispatcher->GetFrame(); 2339cdf0e10cSrcweir while ( pFrame->GetParentViewFrame_Impl() ) 2340cdf0e10cSrcweir pFrame = pFrame->GetParentViewFrame_Impl(); 2341cdf0e10cSrcweir SfxViewFrame* pTop = pFrame->GetTopViewFrame(); 2342cdf0e10cSrcweir return pTop->GetFrame().GetTopWindow_Impl(); 2343cdf0e10cSrcweir } 2344cdf0e10cSrcweir 2345cdf0e10cSrcweir sal_Bool SfxBindings::ExecuteCommand_Impl( const String& rCommand ) 2346cdf0e10cSrcweir { 2347cdf0e10cSrcweir ::com::sun::star::util::URL aURL; 2348cdf0e10cSrcweir aURL.Complete = rCommand; 2349cdf0e10cSrcweir Reference < XURLTransformer > xTrans( ::comphelper::getProcessServiceFactory()->createInstance( rtl::OUString::createFromAscii("com.sun.star.util.URLTransformer" )), UNO_QUERY ); 2350cdf0e10cSrcweir xTrans->parseStrict( aURL ); 2351cdf0e10cSrcweir ::com::sun::star::uno::Reference< ::com::sun::star::frame::XDispatch > xDisp = pImp->xProv->queryDispatch( aURL, ::rtl::OUString(), 0 ); 2352cdf0e10cSrcweir if ( xDisp.is() ) 2353cdf0e10cSrcweir { 2354cdf0e10cSrcweir if(::comphelper::UiEventsLogger::isEnabled()) //#i88653# 2355cdf0e10cSrcweir { 2356cdf0e10cSrcweir ::rtl::OUString sAppName; 2357cdf0e10cSrcweir try 2358cdf0e10cSrcweir { 2359cdf0e10cSrcweir static ::rtl::OUString our_aModuleManagerName = ::rtl::OUString::createFromAscii("com.sun.star.frame.ModuleManager"); 2360cdf0e10cSrcweir ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory > xServiceManager = 2361cdf0e10cSrcweir ::comphelper::getProcessServiceFactory(); 2362cdf0e10cSrcweir ::com::sun::star::uno::Reference< ::com::sun::star::frame::XModuleManager > xModuleManager( 2363cdf0e10cSrcweir xServiceManager->createInstance(our_aModuleManagerName) 2364cdf0e10cSrcweir , ::com::sun::star::uno::UNO_QUERY_THROW); 2365cdf0e10cSrcweir ::com::sun::star::uno::Reference < ::com::sun::star::frame::XFrame > xFrame( 2366cdf0e10cSrcweir pDispatcher->GetFrame()->GetFrame().GetFrameInterface(), UNO_QUERY_THROW); 2367cdf0e10cSrcweir sAppName = xModuleManager->identify(xFrame); 2368cdf0e10cSrcweir } catch(::com::sun::star::uno::Exception&) {} 2369cdf0e10cSrcweir Sequence<beans::PropertyValue> source; 2370cdf0e10cSrcweir ::comphelper::UiEventsLogger::appendDispatchOrigin(source, sAppName, ::rtl::OUString::createFromAscii("SfxAsyncExec")); 2371cdf0e10cSrcweir ::comphelper::UiEventsLogger::logDispatch(aURL, source); 2372cdf0e10cSrcweir } 2373cdf0e10cSrcweir new SfxAsyncExec_Impl( aURL, xDisp ); 2374cdf0e10cSrcweir return sal_True; 2375cdf0e10cSrcweir } 2376cdf0e10cSrcweir 2377cdf0e10cSrcweir return sal_False; 2378cdf0e10cSrcweir } 2379cdf0e10cSrcweir 2380cdf0e10cSrcweir com::sun::star::uno::Reference< com::sun::star::frame::XDispatchRecorder > SfxBindings::GetRecorder() const 2381cdf0e10cSrcweir { 2382cdf0e10cSrcweir return pImp->xRecorder; 2383cdf0e10cSrcweir } 2384cdf0e10cSrcweir 2385cdf0e10cSrcweir void SfxBindings::SetRecorder_Impl( com::sun::star::uno::Reference< com::sun::star::frame::XDispatchRecorder >& rRecorder ) 2386cdf0e10cSrcweir { 2387cdf0e10cSrcweir pImp->xRecorder = rRecorder; 2388cdf0e10cSrcweir } 2389cdf0e10cSrcweir 2390cdf0e10cSrcweir void SfxBindings::ContextChanged_Impl() 2391cdf0e10cSrcweir { 2392cdf0e10cSrcweir if ( !pImp->bInUpdate && ( !pImp->bContextChanged || !pImp->bAllMsgDirty ) ) 2393cdf0e10cSrcweir { 2394cdf0e10cSrcweir InvalidateAll( sal_True ); 2395cdf0e10cSrcweir } 2396cdf0e10cSrcweir } 2397cdf0e10cSrcweir 2398cdf0e10cSrcweir uno::Reference < frame::XDispatch > SfxBindings::GetDispatch( const SfxSlot* pSlot, const util::URL& aURL, sal_Bool bMasterCommand ) 2399cdf0e10cSrcweir { 2400cdf0e10cSrcweir uno::Reference < frame::XDispatch > xRet; 2401cdf0e10cSrcweir SfxStateCache* pCache = GetStateCache( pSlot->nSlotId ); 2402cdf0e10cSrcweir if ( pCache && !bMasterCommand ) 2403cdf0e10cSrcweir xRet = pCache->GetInternalDispatch(); 2404cdf0e10cSrcweir if ( !xRet.is() ) 2405cdf0e10cSrcweir { 2406cdf0e10cSrcweir // dispatches for slaves are unbound, they don't have a state 2407cdf0e10cSrcweir SfxOfficeDispatch* pDispatch = bMasterCommand ? 2408cdf0e10cSrcweir new SfxOfficeDispatch( pDispatcher, pSlot, aURL ) : 2409cdf0e10cSrcweir new SfxOfficeDispatch( *this, pDispatcher, pSlot, aURL ); 2410cdf0e10cSrcweir 2411cdf0e10cSrcweir pDispatch->SetMasterUnoCommand( bMasterCommand ); 2412cdf0e10cSrcweir xRet = uno::Reference < frame::XDispatch >( pDispatch ); 2413cdf0e10cSrcweir if ( !pCache ) 2414cdf0e10cSrcweir pCache = GetStateCache( pSlot->nSlotId ); 2415cdf0e10cSrcweir 2416cdf0e10cSrcweir DBG_ASSERT( pCache, "No cache for OfficeDispatch!" ); 2417cdf0e10cSrcweir if ( pCache && !bMasterCommand ) 2418cdf0e10cSrcweir pCache->SetInternalDispatch( xRet ); 2419cdf0e10cSrcweir } 2420cdf0e10cSrcweir 2421cdf0e10cSrcweir return xRet; 2422cdf0e10cSrcweir } 2423