122de8995SAndre Fischer /************************************************************** 222de8995SAndre Fischer * 322de8995SAndre Fischer * Licensed to the Apache Software Foundation (ASF) under one 422de8995SAndre Fischer * or more contributor license agreements. See the NOTICE file 522de8995SAndre Fischer * distributed with this work for additional information 622de8995SAndre Fischer * regarding copyright ownership. The ASF licenses this file 722de8995SAndre Fischer * to you under the Apache License, Version 2.0 (the 822de8995SAndre Fischer * "License"); you may not use this file except in compliance 922de8995SAndre Fischer * with the License. You may obtain a copy of the License at 1022de8995SAndre Fischer * 1122de8995SAndre Fischer * http://www.apache.org/licenses/LICENSE-2.0 1222de8995SAndre Fischer * 1322de8995SAndre Fischer * Unless required by applicable law or agreed to in writing, 1422de8995SAndre Fischer * software distributed under the License is distributed on an 1522de8995SAndre Fischer * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 1622de8995SAndre Fischer * KIND, either express or implied. See the License for the 1722de8995SAndre Fischer * specific language governing permissions and limitations 1822de8995SAndre Fischer * under the License. 1922de8995SAndre Fischer * 2022de8995SAndre Fischer *************************************************************/ 2122de8995SAndre Fischer 2222de8995SAndre Fischer #include "precompiled_framework.hxx" 2322de8995SAndre Fischer 2422de8995SAndre Fischer #include "services/ContextChangeEventMultiplexer.hxx" 2522de8995SAndre Fischer #include "services.h" 2622de8995SAndre Fischer 2722de8995SAndre Fischer using ::rtl::OUString; 2822de8995SAndre Fischer 2922de8995SAndre Fischer #define A2S(s) ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(s)) 3022de8995SAndre Fischer 3122de8995SAndre Fischer namespace framework { 3222de8995SAndre Fischer 3322de8995SAndre Fischer #define IMPLEMENTATION_NAME "org.apache.openoffice.comp.framework.ContextChangeEventMultiplexer" 3422de8995SAndre Fischer #define SERVICE_NAME "com.sun.star.ui.ContextChangeEventMultiplexer" 3522de8995SAndre Fischer #define SINGLETON_NAME "org.apache.openoffice.comp.framework.ContextChangeEventMultiplexerSigleton" 3622de8995SAndre Fischer 3722de8995SAndre Fischer 3822de8995SAndre Fischer ContextChangeEventMultiplexer::ContextChangeEventMultiplexer ( 39*b9e67834SAndre Fischer const cssu::Reference<cssu::XComponentContext>& rxContext) 4022de8995SAndre Fischer : ContextChangeEventMultiplexerInterfaceBase(m_aMutex), 4122de8995SAndre Fischer maListeners() 4222de8995SAndre Fischer { 4322de8995SAndre Fischer (void)rxContext; 4422de8995SAndre Fischer } 4522de8995SAndre Fischer 4622de8995SAndre Fischer 4722de8995SAndre Fischer 4822de8995SAndre Fischer 4922de8995SAndre Fischer ContextChangeEventMultiplexer::~ContextChangeEventMultiplexer (void) 5022de8995SAndre Fischer { 51*b9e67834SAndre Fischer } 52*b9e67834SAndre Fischer 53*b9e67834SAndre Fischer 54*b9e67834SAndre Fischer 55*b9e67834SAndre Fischer 56*b9e67834SAndre Fischer void SAL_CALL ContextChangeEventMultiplexer::disposing (void) 57*b9e67834SAndre Fischer { 58*b9e67834SAndre Fischer ListenerMap aListeners; 59*b9e67834SAndre Fischer aListeners.swap(maListeners); 60*b9e67834SAndre Fischer 61*b9e67834SAndre Fischer css::lang::EventObject aEvent (cssu::Reference<cssu::XInterface>(static_cast<XWeak*>(this))); 62*b9e67834SAndre Fischer for (ListenerMap::const_iterator iContainer(aListeners.begin()), iEnd(aListeners.end()); 63*b9e67834SAndre Fischer iContainer!=iEnd; 64*b9e67834SAndre Fischer ++iContainer) 65*b9e67834SAndre Fischer { 66*b9e67834SAndre Fischer for (ListenerContainer::const_iterator 67*b9e67834SAndre Fischer iListener(iContainer->second.begin()), 68*b9e67834SAndre Fischer iContainerEnd(iContainer->second.end()); 69*b9e67834SAndre Fischer iListener!=iContainerEnd; 70*b9e67834SAndre Fischer ++iListener) 71*b9e67834SAndre Fischer { 72*b9e67834SAndre Fischer (*iListener)->disposing(aEvent); 73*b9e67834SAndre Fischer } 74*b9e67834SAndre Fischer } 7522de8995SAndre Fischer } 7622de8995SAndre Fischer 7722de8995SAndre Fischer 7822de8995SAndre Fischer 7922de8995SAndre Fischer 8022de8995SAndre Fischer // XContextChangeEventMultiplexer 8122de8995SAndre Fischer 8222de8995SAndre Fischer void SAL_CALL ContextChangeEventMultiplexer::addContextChangeEventListener ( 8322de8995SAndre Fischer const cssu::Reference<css::ui::XContextChangeEventListener>& rxListener, 8422de8995SAndre Fischer const cssu::Reference<cssu::XInterface>& rxEventFocus) 8522de8995SAndre Fischer throw(cssu::RuntimeException,cssl::IllegalArgumentException) 8622de8995SAndre Fischer { 8722de8995SAndre Fischer if ( ! rxListener.is()) 8822de8995SAndre Fischer throw css::lang::IllegalArgumentException( 8922de8995SAndre Fischer A2S("can not add an empty reference"), 9022de8995SAndre Fischer static_cast<XWeak*>(this), 9122de8995SAndre Fischer 0); 9222de8995SAndre Fischer 9322de8995SAndre Fischer ListenerMap::iterator iListenerContainer (maListeners.find(rxEventFocus)); 9422de8995SAndre Fischer if (iListenerContainer == maListeners.end()) 9522de8995SAndre Fischer { 9622de8995SAndre Fischer // Create a new listener container for the event focus. 9722de8995SAndre Fischer iListenerContainer = maListeners.insert( 9822de8995SAndre Fischer ListenerMap::value_type( 9922de8995SAndre Fischer rxEventFocus, 10022de8995SAndre Fischer ListenerContainer())).first; 10122de8995SAndre Fischer } 10222de8995SAndre Fischer if (iListenerContainer != maListeners.end()) 10322de8995SAndre Fischer { 10422de8995SAndre Fischer ListenerContainer& rContainer (iListenerContainer->second); 10522de8995SAndre Fischer if (::std::find(rContainer.begin(), rContainer.end(), rxListener) == rContainer.end()) 10622de8995SAndre Fischer rContainer.push_back(rxListener); 10722de8995SAndre Fischer else 10822de8995SAndre Fischer { 10922de8995SAndre Fischer // The listener was added for the same event focus 11022de8995SAndre Fischer // previously. That is an error. 11122de8995SAndre Fischer throw cssl::IllegalArgumentException(A2S("listener added twice"), static_cast<XWeak*>(this), 0); 11222de8995SAndre Fischer } 11322de8995SAndre Fischer } 11422de8995SAndre Fischer } 11522de8995SAndre Fischer 11622de8995SAndre Fischer 11722de8995SAndre Fischer 11822de8995SAndre Fischer 11922de8995SAndre Fischer void SAL_CALL ContextChangeEventMultiplexer::removeContextChangeEventListener ( 12022de8995SAndre Fischer const cssu::Reference<css::ui::XContextChangeEventListener>& rxListener, 12122de8995SAndre Fischer const cssu::Reference<cssu::XInterface>& rxEventFocus) 12222de8995SAndre Fischer throw(cssu::RuntimeException,cssl::IllegalArgumentException) 12322de8995SAndre Fischer { 12422de8995SAndre Fischer if ( ! rxListener.is()) 12522de8995SAndre Fischer throw cssl::IllegalArgumentException(A2S("can not remove an empty reference"), static_cast<XWeak*>(this), 0); 12622de8995SAndre Fischer 12722de8995SAndre Fischer ListenerMap::iterator iListenerContainer (maListeners.find(rxEventFocus)); 12822de8995SAndre Fischer if (iListenerContainer != maListeners.end()) 12922de8995SAndre Fischer { 13022de8995SAndre Fischer ListenerContainer& rContainer (iListenerContainer->second); 13122de8995SAndre Fischer const ListenerContainer::iterator iListener (::std::find(rContainer.begin(), rContainer.end(), rxListener)); 13222de8995SAndre Fischer if (iListener != rContainer.end()) 133*b9e67834SAndre Fischer { 13422de8995SAndre Fischer rContainer.erase(iListener); 135*b9e67834SAndre Fischer 136*b9e67834SAndre Fischer // Remove the listener container as well when its last 137*b9e67834SAndre Fischer // listener was just removed. This prevents us from 138*b9e67834SAndre Fischer // holding the focus alive. 139*b9e67834SAndre Fischer if (rContainer.empty()) 140*b9e67834SAndre Fischer maListeners.erase(iListenerContainer); 141*b9e67834SAndre Fischer } 14222de8995SAndre Fischer } 14322de8995SAndre Fischer 14422de8995SAndre Fischer } 14522de8995SAndre Fischer 14622de8995SAndre Fischer 14722de8995SAndre Fischer 14822de8995SAndre Fischer 14922de8995SAndre Fischer void SAL_CALL ContextChangeEventMultiplexer::removeAllContextChangeEventListeners ( 15022de8995SAndre Fischer const cssu::Reference<css::ui::XContextChangeEventListener>& rxListener) 15122de8995SAndre Fischer throw(cssu::RuntimeException,cssl::IllegalArgumentException) 15222de8995SAndre Fischer { 15322de8995SAndre Fischer if ( ! rxListener.is()) 15422de8995SAndre Fischer throw cssl::IllegalArgumentException(A2S("can not remove an empty reference"), static_cast<XWeak*>(this), 0); 15522de8995SAndre Fischer 156*b9e67834SAndre Fischer ::std::vector<cssu::Reference<cssu::XInterface> > aContainersToRemove; 15722de8995SAndre Fischer for (ListenerMap::iterator 15822de8995SAndre Fischer iContainer(maListeners.begin()), 15922de8995SAndre Fischer iEnd(maListeners.end()); 16022de8995SAndre Fischer iContainer!=iEnd; 16122de8995SAndre Fischer ++iContainer) 16222de8995SAndre Fischer { 16322de8995SAndre Fischer const ListenerContainer::iterator iListener (::std::find(iContainer->second.begin(), iContainer->second.end(), rxListener)); 16422de8995SAndre Fischer if (iListener != iContainer->second.end()) 165*b9e67834SAndre Fischer { 16622de8995SAndre Fischer iContainer->second.erase(iListener); 167*b9e67834SAndre Fischer 168*b9e67834SAndre Fischer // When we just removed the last listener then mark the 169*b9e67834SAndre Fischer // container as to be removed. 170*b9e67834SAndre Fischer if (iContainer->second.empty()) 171*b9e67834SAndre Fischer aContainersToRemove.push_back(iContainer->first); 172*b9e67834SAndre Fischer } 173*b9e67834SAndre Fischer } 174*b9e67834SAndre Fischer 175*b9e67834SAndre Fischer for (::std::vector<cssu::Reference<cssu::XInterface> >::iterator 176*b9e67834SAndre Fischer iFocus(aContainersToRemove.begin()), 177*b9e67834SAndre Fischer iEnd(aContainersToRemove.end()); 178*b9e67834SAndre Fischer iFocus!=iEnd; 179*b9e67834SAndre Fischer ++iFocus) 180*b9e67834SAndre Fischer { 181*b9e67834SAndre Fischer maListeners.erase(*iFocus); 18222de8995SAndre Fischer } 18322de8995SAndre Fischer } 18422de8995SAndre Fischer 18522de8995SAndre Fischer 18622de8995SAndre Fischer 18722de8995SAndre Fischer 18822de8995SAndre Fischer 18922de8995SAndre Fischer void SAL_CALL ContextChangeEventMultiplexer::broadcastContextChangeEvent ( 19022de8995SAndre Fischer const css::ui::ContextChangeEventObject& rEventObject, 19122de8995SAndre Fischer const cssu::Reference<cssu::XInterface>& rxEventFocus) 19222de8995SAndre Fischer throw(cssu::RuntimeException) 19322de8995SAndre Fischer { 19422de8995SAndre Fischer BroadcastEventToSingleContainer(rEventObject, rxEventFocus); 19522de8995SAndre Fischer if (rxEventFocus.is()) 19622de8995SAndre Fischer BroadcastEventToSingleContainer(rEventObject, NULL); 19722de8995SAndre Fischer } 19822de8995SAndre Fischer 19922de8995SAndre Fischer 20022de8995SAndre Fischer 20122de8995SAndre Fischer 20222de8995SAndre Fischer void ContextChangeEventMultiplexer::BroadcastEventToSingleContainer ( 20322de8995SAndre Fischer const css::ui::ContextChangeEventObject& rEventObject, 20422de8995SAndre Fischer const cssu::Reference<cssu::XInterface>& rxEventFocus) 20522de8995SAndre Fischer { 20622de8995SAndre Fischer ListenerMap::iterator iListenerContainer (maListeners.find(rxEventFocus)); 20722de8995SAndre Fischer if (iListenerContainer != maListeners.end()) 20822de8995SAndre Fischer { 20922de8995SAndre Fischer // Create a copy of the listener container to avoid problems 21022de8995SAndre Fischer // when one of the called listeners calls add... or remove... 21122de8995SAndre Fischer ListenerContainer aContainer (iListenerContainer->second); 21222de8995SAndre Fischer for (ListenerContainer::const_iterator 21322de8995SAndre Fischer iListener(aContainer.begin()), 21422de8995SAndre Fischer iEnd(aContainer.end()); 21522de8995SAndre Fischer iListener!=iEnd; 21622de8995SAndre Fischer ++iListener) 21722de8995SAndre Fischer { 21822de8995SAndre Fischer (*iListener)->notifyContextChangeEvent(rEventObject); 21922de8995SAndre Fischer } 22022de8995SAndre Fischer } 22122de8995SAndre Fischer } 22222de8995SAndre Fischer 22322de8995SAndre Fischer 22422de8995SAndre Fischer 22522de8995SAndre Fischer 22622de8995SAndre Fischer // XSingleComponentFactory 22722de8995SAndre Fischer 22822de8995SAndre Fischer cssu::Reference<cssu::XInterface> SAL_CALL ContextChangeEventMultiplexer::createInstanceWithContext ( 22922de8995SAndre Fischer const cssu::Reference<cssu::XComponentContext>& rxContext) 23022de8995SAndre Fischer throw (cssu::Exception, cssu::RuntimeException) 23122de8995SAndre Fischer { 23222de8995SAndre Fischer (void)rxContext; 23322de8995SAndre Fischer return cssu::Reference<cssu::XInterface>(); 23422de8995SAndre Fischer } 23522de8995SAndre Fischer 23622de8995SAndre Fischer 23722de8995SAndre Fischer 23822de8995SAndre Fischer 23922de8995SAndre Fischer cssu::Reference<cssu::XInterface > SAL_CALL ContextChangeEventMultiplexer::createInstanceWithArgumentsAndContext ( 24022de8995SAndre Fischer const cssu::Sequence<cssu::Any>& rArguments, 24122de8995SAndre Fischer const cssu::Reference<cssu::XComponentContext>& rxContext) 24222de8995SAndre Fischer throw (cssu::Exception, cssu::RuntimeException) 24322de8995SAndre Fischer { 24422de8995SAndre Fischer (void)rArguments; 24522de8995SAndre Fischer (void)rxContext; 24622de8995SAndre Fischer return cssu::Reference<cssu::XInterface>(); 24722de8995SAndre Fischer } 24822de8995SAndre Fischer 24922de8995SAndre Fischer 25022de8995SAndre Fischer 25122de8995SAndre Fischer 25222de8995SAndre Fischer // XServiceInfo 25322de8995SAndre Fischer 25422de8995SAndre Fischer ::rtl::OUString SAL_CALL ContextChangeEventMultiplexer::getImplementationName (void) 25522de8995SAndre Fischer throw(cssu::RuntimeException) 25622de8995SAndre Fischer { 25722de8995SAndre Fischer return impl_getStaticImplementationName(); 25822de8995SAndre Fischer } 25922de8995SAndre Fischer 26022de8995SAndre Fischer 26122de8995SAndre Fischer 26222de8995SAndre Fischer 26322de8995SAndre Fischer 26422de8995SAndre Fischer sal_Bool SAL_CALL ContextChangeEventMultiplexer::supportsService ( 26522de8995SAndre Fischer const ::rtl::OUString& rsServiceName) 26622de8995SAndre Fischer throw (cssu::RuntimeException) 26722de8995SAndre Fischer { 26822de8995SAndre Fischer return ::comphelper::findValue(static_GetSupportedServiceNames(), rsServiceName, sal_True).getLength() != 0; 26922de8995SAndre Fischer } 27022de8995SAndre Fischer 27122de8995SAndre Fischer 27222de8995SAndre Fischer 27322de8995SAndre Fischer 27422de8995SAndre Fischer cssu::Sequence<OUString> SAL_CALL ContextChangeEventMultiplexer::getSupportedServiceNames (void) 27522de8995SAndre Fischer throw (cssu::RuntimeException) 27622de8995SAndre Fischer { 27722de8995SAndre Fischer return static_GetSupportedServiceNames(); 27822de8995SAndre Fischer } 27922de8995SAndre Fischer 28022de8995SAndre Fischer 28122de8995SAndre Fischer 28222de8995SAndre Fischer 28322de8995SAndre Fischer // Local and static methods. 28422de8995SAndre Fischer 28522de8995SAndre Fischer OUString SAL_CALL ContextChangeEventMultiplexer::impl_getStaticImplementationName (void) 28622de8995SAndre Fischer { 28722de8995SAndre Fischer return A2S(IMPLEMENTATION_NAME); 28822de8995SAndre Fischer } 28922de8995SAndre Fischer 29022de8995SAndre Fischer 29122de8995SAndre Fischer 29222de8995SAndre Fischer 29322de8995SAndre Fischer cssu::Sequence<OUString> SAL_CALL ContextChangeEventMultiplexer::static_GetSupportedServiceNames (void) 29422de8995SAndre Fischer { 29522de8995SAndre Fischer cssu::Sequence<OUString> aServiceNames (2); 29622de8995SAndre Fischer aServiceNames[0] = A2S(SERVICE_NAME); 29722de8995SAndre Fischer aServiceNames[1] = A2S(SINGLETON_NAME); 29822de8995SAndre Fischer return aServiceNames; 29922de8995SAndre Fischer } 30022de8995SAndre Fischer 30122de8995SAndre Fischer 30222de8995SAndre Fischer 30322de8995SAndre Fischer 30422de8995SAndre Fischer cssu::Reference<cssu::XInterface> ContextChangeEventMultiplexer::impl_createFactory ( 30522de8995SAndre Fischer const cssu::Reference<cssl::XMultiServiceFactory>& rxServiceManager) 30622de8995SAndre Fischer { 30722de8995SAndre Fischer (void)rxServiceManager; 30822de8995SAndre Fischer return cppu::createSingleComponentFactory( 30922de8995SAndre Fischer ContextChangeEventMultiplexer::static_CreateInstance, 31022de8995SAndre Fischer ContextChangeEventMultiplexer::impl_getStaticImplementationName(), 31122de8995SAndre Fischer ContextChangeEventMultiplexer::static_GetSupportedServiceNames() 31222de8995SAndre Fischer ); 31322de8995SAndre Fischer } 31422de8995SAndre Fischer 31522de8995SAndre Fischer 31622de8995SAndre Fischer 31722de8995SAndre Fischer 31822de8995SAndre Fischer cssu::Reference<cssu::XInterface> SAL_CALL ContextChangeEventMultiplexer::static_CreateInstance ( 31922de8995SAndre Fischer const cssu::Reference<cssu::XComponentContext>& rxComponentContext) 32022de8995SAndre Fischer throw (cssu::Exception) 32122de8995SAndre Fischer { 32222de8995SAndre Fischer ContextChangeEventMultiplexer* pObject = new ContextChangeEventMultiplexer(rxComponentContext); 32322de8995SAndre Fischer cssu::Reference<cssu::XInterface> xService (static_cast<XWeak*>(pObject), cssu::UNO_QUERY); 32422de8995SAndre Fischer return xService; 32522de8995SAndre Fischer } 32622de8995SAndre Fischer 32722de8995SAndre Fischer } // end of namespace framework 328