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 #include "precompiled_framework.hxx" 23 24 #include "services/EventMultiplexer.hxx" 25 #include "services.h" 26 27 using ::rtl::OUString; 28 29 #define A2S(s) ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(s)) 30 31 namespace framework { 32 33 #define IMPLEMENTATION_NAME "org.apache.openoffice.comp.framework.EventMultiplexer" 34 #define SERVICE_NAME "com.sun.star.ui.ContextChangeEventMultiplexer" 35 #define SINGLETON_NAME "org.apache.openoffice.comp.framework.EventMultiplexer" 36 37 38 EventMultiplexer::EventMultiplexer (const cssu::Reference<css::uno::XComponentContext>& rxContext) 39 : EventMultiplexerInterfaceBase(m_aMutex), 40 maListeners() 41 { 42 (void)rxContext; 43 } 44 45 46 47 48 EventMultiplexer::~EventMultiplexer (void) 49 { 50 maListeners.clear(); 51 } 52 53 54 55 56 // XEventMultiplexer 57 58 void SAL_CALL EventMultiplexer::addEventListener ( 59 const cssu::Reference<css::util::XEventListener>& rxListener, 60 const cssu::Reference<cssu::XInterface>& rxEventFocus) 61 { 62 if ( ! rxListener.is()) 63 throw css::lang::IllegalArgumentException(A2S("can not add an empty reference"), static_cast<XWeak*>(this), 0); 64 65 ListenerMap::iterator iListenerContainer (maListeners.find(rxEventFocus)); 66 if (iListenerContainer == maListeners.end()) 67 { 68 // Create a new listener container for the event focus. 69 iListenerContainer = maListeners.insert( 70 ListenerMap::value_type( 71 rxEventFocus, 72 ListenerContainer())).first; 73 } 74 if (iListenerContainer != maListeners.end()) 75 { 76 ListenerContainer& rContainer (iListenerContainer->second); 77 if (::std::find(rContainer.begin(), rContainer.end(), rxListener) == rContainer.end()) 78 rContainer.push_back(rxListener); 79 else 80 { 81 // The listener was added for the same event focus 82 // previously. That is an error. 83 throw cssl::IllegalArgumentException(A2S("listener added twice"), static_cast<XWeak*>(this), 0); 84 } 85 } 86 } 87 88 89 90 91 void SAL_CALL EventMultiplexer::removeEventListener ( 92 const cssu::Reference<css::util::XEventListener>& rxListener, 93 const cssu::Reference<cssu::XInterface>& rxEventFocus) 94 { 95 if ( ! rxListener.is()) 96 throw cssl::IllegalArgumentException(A2S("can not remove an empty reference"), static_cast<XWeak*>(this), 0); 97 98 ListenerMap::iterator iListenerContainer (maListeners.find(rxEventFocus)); 99 if (iListenerContainer != maListeners.end()) 100 { 101 ListenerContainer& rContainer (iListenerContainer->second); 102 const ListenerContainer::iterator iListener (::std::find(rContainer.begin(), rContainer.end(), rxListener)); 103 if (iListener != rContainer.end()) 104 rContainer.erase(iListener); 105 } 106 107 } 108 109 110 111 112 void SAL_CALL EventMultiplexer::removeAllEventListeners ( 113 const cssu::Reference<css::util::XEventListener>& rxListener) 114 { 115 if ( ! rxListener.is()) 116 throw cssl::IllegalArgumentException(A2S("can not remove an empty reference"), static_cast<XWeak*>(this), 0); 117 118 for (ListenerMap::iterator 119 iContainer(maListeners.begin()), 120 iEnd(maListeners.end()); 121 iContainer!=iEnd; 122 ++iContainer) 123 { 124 const ListenerContainer::iterator iListener (::std::find(iContainer->second.begin(), iContainer->second.end(), rxListener)); 125 if (iListener != iContainer->second.end()) 126 iContainer->second.erase(iListener); 127 } 128 } 129 130 131 132 133 134 void SAL_CALL EventMultiplexer::broadcastEvent ( 135 const cssl::EventObject& rEventObject, 136 const cssu::Reference<cssu::XInterface>& rxEventFocus) 137 { 138 BroadcastEventToSingleContainer(rEventObject, rxEventFocus); 139 if (rxEventFocus.is()) 140 BroadcastEventToSingleContainer(rEventObject, NULL); 141 } 142 143 144 145 146 void EventMultiplexer::BroadcastEventToSingleContainer ( 147 const cssl::EventObject& rEventObject, 148 const cssu::Reference<cssu::XInterface>& rxEventFocus) 149 { 150 ListenerMap::iterator iListenerContainer (maListeners.find(rxEventFocus)); 151 if (iListenerContainer != maListeners.end()) 152 { 153 // Create a copy of the listener container to avoid problems 154 // when one of the called listeners calls add... or remove... 155 ListenerContainer aContainer (iListenerContainer->second); 156 for (ListenerContainer::const_iterator 157 iListener(aContainer.begin()), 158 iEnd(aContainer.end()); 159 iListener!=iEnd; 160 ++iListener) 161 { 162 (*iListener)->notifyEvent(rEventObject); 163 } 164 } 165 } 166 167 168 169 170 // XSingleComponentFactory 171 cssu::Reference<cssu::XInterface> SAL_CALL EventMultiplexer::createInstanceWithContext ( 172 const cssu::Reference<cssu::XComponentContext>& rxContext) 173 { 174 return cssu::Reference<cssu::XInterface>(); 175 } 176 177 178 179 180 cssu::Reference<cssu::XInterface > SAL_CALL EventMultiplexer::createInstanceWithArgumentsAndContext ( 181 const cssu::Sequence<cssu::Any>& rArguments, 182 const cssu::Reference<cssu::XComponentContext>& rxContext) 183 { 184 return cssu::Reference<cssu::XInterface>(); 185 } 186 187 188 189 190 // XServiceInfo 191 192 ::rtl::OUString SAL_CALL EventMultiplexer::getImplementationName (void) 193 { 194 return impl_getStaticImplementationName(); 195 } 196 197 198 199 200 201 sal_Bool SAL_CALL EventMultiplexer::supportsService ( 202 const ::rtl::OUString& rsServiceName) 203 { 204 return ::comphelper::findValue(static_GetSupportedServiceNames(), rsServiceName, sal_True).getLength() != 0; 205 } 206 207 208 209 210 cssu::Sequence<OUString> SAL_CALL EventMultiplexer::getSupportedServiceNames (void) 211 { 212 return static_GetSupportedServiceNames(); 213 } 214 215 216 217 218 // Local and static methods. 219 220 OUString SAL_CALL EventMultiplexer::impl_getStaticImplementationName (void) 221 { 222 return A2S(IMPLEMENTATION_NAME); 223 } 224 225 226 227 228 cssu::Sequence<OUString> SAL_CALL EventMultiplexer::static_GetSupportedServiceNames (void) 229 { 230 cssu::Sequence<OUString> aServiceNames (2); 231 aServiceNames[0] = A2S(SERVICE_NAME); 232 aServiceNames[1] = A2S(SINGLETON_NAME); 233 return aServiceNames; 234 } 235 236 237 238 239 cssu::Reference<cssu::XInterface> EventMultiplexer::impl_createFactory ( 240 const cssu::Reference<cssl::XMultiServiceFactory>& rxServiceManager) 241 { 242 return cppu::createSingleComponentFactory( 243 EventMultiplexer::static_CreateInstance, 244 EventMultiplexer::impl_getStaticImplementationName(), 245 EventMultiplexer::static_GetSupportedServiceNames() 246 ); 247 } 248 249 250 251 252 cssu::Reference<cssu::XInterface> SAL_CALL EventMultiplexer::static_CreateInstance ( 253 const cssu::Reference<cssu::XComponentContext>& rxComponentContext) 254 { 255 EventMultiplexer* pObject = new EventMultiplexer(rxComponentContext); 256 cssu::Reference<cssu::XInterface> xService (static_cast<XWeak*>(pObject), cssu::UNO_QUERY); 257 return xService; 258 } 259 260 } // end of namespace framework 261