1 /************************************************************** 2 * 3 * Licensed to the Apache Software Foundation (ASF) under one 4 * or more contributor license agreements. See the NOTICE file 5 * distributed with this work for additional information 6 * regarding copyright ownership. The ASF licenses this file 7 * to you under the Apache License, Version 2.0 (the 8 * "License"); you may not use this file except in compliance 9 * with the License. You may obtain a copy of the License at 10 * 11 * http://www.apache.org/licenses/LICENSE-2.0 12 * 13 * Unless required by applicable law or agreed to in writing, 14 * software distributed under the License is distributed on an 15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 * KIND, either express or implied. See the License for the 17 * specific language governing permissions and limitations 18 * under the License. 19 * 20 *************************************************************/ 21 22 23 24 // MARKER(update_precomp.py): autogen include statement, do not remove 25 #include "precompiled_svl.hxx" 26 27 #ifndef GCC 28 #endif 29 #include <tools/debug.hxx> 30 31 #include <svl/hint.hxx> 32 #include <svl/smplhint.hxx> 33 #include <svl/lstner.hxx> 34 35 SV_DECL_PTRARR( SfxListenerArr_Impl, SfxListener*, 0, 2 ) 36 37 #define _SFX_BRDCST_CXX 38 #include <svl/brdcst.hxx> 39 40 //==================================================================== 41 DBG_NAME(SfxBroadcaster) 42 TYPEINIT0(SfxBroadcaster); 43 44 //==================================================================== 45 46 //==================================================================== 47 // broadcast immediately 48 49 50 void SfxBroadcaster::Broadcast( const SfxHint &rHint ) 51 { 52 DBG_CHKTHIS(SfxBroadcaster, 0); 53 54 // is anybody to notify? 55 if ( aListeners.Count() /*! || aGlobListeners.Count() */ ) 56 { 57 // notify all registered listeners exactly once 58 for ( sal_uInt16 n = 0; n < aListeners.Count(); ++n ) 59 { 60 SfxListener* pListener = aListeners[n]; 61 if ( pListener ) 62 pListener->Notify( *this, rHint ); 63 } 64 } 65 } 66 67 //-------------------------------------------------------------------- 68 69 // broadcast after a timeout 70 71 72 void SfxBroadcaster::BroadcastDelayed( const SfxHint& rHint ) 73 { 74 DBG_WARNING( "not implemented" ); 75 Broadcast(rHint); 76 } 77 //-------------------------------------------------------------------- 78 79 // broadcast in idle-handler 80 81 void SfxBroadcaster::BroadcastInIdle( const SfxHint& rHint ) 82 { 83 DBG_WARNING( "not implemented" ); 84 Broadcast(rHint); 85 } 86 //-------------------------------------------------------------------- 87 88 // unregister all listeners 89 90 SfxBroadcaster::~SfxBroadcaster() 91 { 92 DBG_DTOR(SfxBroadcaster, 0); 93 94 Broadcast( SfxSimpleHint(SFX_HINT_DYING) ); 95 96 // remove all still registered listeners 97 for ( sal_uInt16 nPos = 0; nPos < aListeners.Count(); ++nPos ) 98 { 99 SfxListener *pListener = aListeners[nPos]; 100 if ( pListener ) 101 pListener->RemoveBroadcaster_Impl(*this); 102 } 103 } 104 105 //-------------------------------------------------------------------- 106 107 // simple ctor of class SfxBroadcaster 108 109 SfxBroadcaster::SfxBroadcaster() 110 { 111 DBG_CTOR(SfxBroadcaster, 0); 112 } 113 114 //-------------------------------------------------------------------- 115 116 // copy ctor of class SfxBroadcaster 117 118 119 SfxBroadcaster::SfxBroadcaster( const SfxBroadcaster &rBC ) 120 { 121 DBG_CTOR(SfxBroadcaster, 0); 122 123 for ( sal_uInt16 n = 0; n < rBC.aListeners.Count(); ++n ) 124 { 125 SfxListener *pListener = rBC.aListeners[n]; 126 if ( pListener ) 127 pListener->StartListening( *this ); 128 } 129 } 130 131 //-------------------------------------------------------------------- 132 133 // add a new SfxListener to the list 134 135 sal_Bool SfxBroadcaster::AddListener( SfxListener& rListener ) 136 { 137 DBG_CHKTHIS(SfxBroadcaster, 0); 138 const SfxListener *pListener = &rListener; 139 const SfxListener *pNull = 0; 140 sal_uInt16 nFreePos = aListeners.GetPos( pNull ); 141 if ( nFreePos < aListeners.Count() ) 142 aListeners.GetData()[nFreePos] = pListener; 143 else if ( aListeners.Count() < (USHRT_MAX-1) ) 144 aListeners.Insert( pListener, aListeners.Count() ); 145 else 146 { 147 DBG_ERROR( "array overflow" ); 148 return sal_False; 149 } 150 151 DBG_ASSERT( USHRT_MAX != aListeners.GetPos(pListener), 152 "AddListener failed" ); 153 return sal_True; 154 } 155 156 //-------------------------------------------------------------------- 157 158 // called, if no more listeners exists 159 160 void SfxBroadcaster::ListenersGone() 161 { 162 DBG_CHKTHIS(SfxBroadcaster,0); 163 } 164 165 //-------------------------------------------------------------------- 166 167 // forward a notification to all registered listeners 168 169 void SfxBroadcaster::Forward(SfxBroadcaster& rBC, const SfxHint& rHint) 170 { 171 const sal_uInt16 nCount = aListeners.Count(); 172 for ( sal_uInt16 i = 0; i < nCount; ++i ) 173 { 174 SfxListener *pListener = aListeners[i]; 175 if ( pListener ) 176 pListener->Notify( rBC, rHint ); 177 } 178 } 179 180 //-------------------------------------------------------------------- 181 182 // remove one SfxListener from the list 183 184 void SfxBroadcaster::RemoveListener( SfxListener& rListener ) 185 { 186 {DBG_CHKTHIS(SfxBroadcaster, 0);} 187 const SfxListener *pListener = &rListener; 188 sal_uInt16 nPos = aListeners.GetPos(pListener); 189 DBG_ASSERT( nPos != USHRT_MAX, "RemoveListener: Listener unknown" ); 190 aListeners.GetData()[nPos] = 0; 191 if ( !HasListeners() ) 192 ListenersGone(); 193 } 194 195 //-------------------------------------------------------------------- 196 197 sal_Bool SfxBroadcaster::HasListeners() const 198 { 199 for ( sal_uInt16 n = 0; n < aListeners.Count(); ++n ) 200 if ( aListeners.GetObject(n) != 0 ) 201 return sal_True; 202 return sal_False; 203 } 204 205 //-------------------------------------------------------------------- 206