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 ( 39b9e67834SAndre 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 { 51b9e67834SAndre Fischer } 52b9e67834SAndre Fischer 53b9e67834SAndre Fischer 54b9e67834SAndre Fischer 55b9e67834SAndre Fischer 56b9e67834SAndre Fischer void SAL_CALL ContextChangeEventMultiplexer::disposing (void) 57b9e67834SAndre Fischer { 58b9e67834SAndre Fischer ListenerMap aListeners; 59b9e67834SAndre Fischer aListeners.swap(maListeners); 60b9e67834SAndre Fischer 61*95a18594SAndre Fischer cssu::Reference<cssu::XInterface> xThis (static_cast<XWeak*>(this)); 62*95a18594SAndre Fischer css::lang::EventObject aEvent (xThis); 63b9e67834SAndre Fischer for (ListenerMap::const_iterator iContainer(aListeners.begin()), iEnd(aListeners.end()); 64b9e67834SAndre Fischer iContainer!=iEnd; 65b9e67834SAndre Fischer ++iContainer) 66b9e67834SAndre Fischer { 67b9e67834SAndre Fischer for (ListenerContainer::const_iterator 68*95a18594SAndre Fischer iListener(iContainer->second.maListeners.begin()), 69*95a18594SAndre Fischer iContainerEnd(iContainer->second.maListeners.end()); 70b9e67834SAndre Fischer iListener!=iContainerEnd; 71b9e67834SAndre Fischer ++iListener) 72b9e67834SAndre Fischer { 73b9e67834SAndre Fischer (*iListener)->disposing(aEvent); 74b9e67834SAndre Fischer } 75b9e67834SAndre Fischer } 7622de8995SAndre Fischer } 7722de8995SAndre Fischer 7822de8995SAndre Fischer 7922de8995SAndre Fischer 8022de8995SAndre Fischer 8122de8995SAndre Fischer // XContextChangeEventMultiplexer 8222de8995SAndre Fischer 8322de8995SAndre Fischer void SAL_CALL ContextChangeEventMultiplexer::addContextChangeEventListener ( 8422de8995SAndre Fischer const cssu::Reference<css::ui::XContextChangeEventListener>& rxListener, 8522de8995SAndre Fischer const cssu::Reference<cssu::XInterface>& rxEventFocus) 8622de8995SAndre Fischer throw(cssu::RuntimeException,cssl::IllegalArgumentException) 8722de8995SAndre Fischer { 8822de8995SAndre Fischer if ( ! rxListener.is()) 8922de8995SAndre Fischer throw css::lang::IllegalArgumentException( 9022de8995SAndre Fischer A2S("can not add an empty reference"), 9122de8995SAndre Fischer static_cast<XWeak*>(this), 9222de8995SAndre Fischer 0); 9322de8995SAndre Fischer 94*95a18594SAndre Fischer ListenerMap::iterator iDescriptor (maListeners.find(rxEventFocus)); 95*95a18594SAndre Fischer if (iDescriptor == maListeners.end()) 9622de8995SAndre Fischer { 9722de8995SAndre Fischer // Create a new listener container for the event focus. 98*95a18594SAndre Fischer iDescriptor = maListeners.insert( 9922de8995SAndre Fischer ListenerMap::value_type( 10022de8995SAndre Fischer rxEventFocus, 101*95a18594SAndre Fischer FocusDescriptor())).first; 10222de8995SAndre Fischer } 103*95a18594SAndre Fischer if (iDescriptor != maListeners.end()) 10422de8995SAndre Fischer { 105*95a18594SAndre Fischer ListenerContainer& rContainer (iDescriptor->second.maListeners); 10622de8995SAndre Fischer if (::std::find(rContainer.begin(), rContainer.end(), rxListener) == rContainer.end()) 10722de8995SAndre Fischer rContainer.push_back(rxListener); 10822de8995SAndre Fischer else 10922de8995SAndre Fischer { 11022de8995SAndre Fischer // The listener was added for the same event focus 11122de8995SAndre Fischer // previously. That is an error. 11222de8995SAndre Fischer throw cssl::IllegalArgumentException(A2S("listener added twice"), static_cast<XWeak*>(this), 0); 11322de8995SAndre Fischer } 11422de8995SAndre Fischer } 115*95a18594SAndre Fischer 116*95a18594SAndre Fischer // Send out an initial event that informs the new listener about 117*95a18594SAndre Fischer // the current context. 118*95a18594SAndre Fischer if (rxEventFocus.is() && iDescriptor != maListeners.end()) 119*95a18594SAndre Fischer { 120*95a18594SAndre Fischer css::ui::ContextChangeEventObject aEvent ( 121*95a18594SAndre Fischer NULL, 122*95a18594SAndre Fischer iDescriptor->second.msCurrentApplicationName, 123*95a18594SAndre Fischer iDescriptor->second.msCurrentContextName); 124*95a18594SAndre Fischer rxListener->notifyContextChangeEvent(aEvent); 125*95a18594SAndre Fischer } 12622de8995SAndre Fischer } 12722de8995SAndre Fischer 12822de8995SAndre Fischer 12922de8995SAndre Fischer 13022de8995SAndre Fischer 13122de8995SAndre Fischer void SAL_CALL ContextChangeEventMultiplexer::removeContextChangeEventListener ( 13222de8995SAndre Fischer const cssu::Reference<css::ui::XContextChangeEventListener>& rxListener, 13322de8995SAndre Fischer const cssu::Reference<cssu::XInterface>& rxEventFocus) 13422de8995SAndre Fischer throw(cssu::RuntimeException,cssl::IllegalArgumentException) 13522de8995SAndre Fischer { 13622de8995SAndre Fischer if ( ! rxListener.is()) 137*95a18594SAndre Fischer throw cssl::IllegalArgumentException( 138*95a18594SAndre Fischer A2S("can not remove an empty reference"), 139*95a18594SAndre Fischer static_cast<XWeak*>(this), 0); 14022de8995SAndre Fischer 141*95a18594SAndre Fischer ListenerMap::iterator iDescriptor (maListeners.find(rxEventFocus)); 142*95a18594SAndre Fischer if (iDescriptor != maListeners.end()) 14322de8995SAndre Fischer { 144*95a18594SAndre Fischer ListenerContainer& rContainer (iDescriptor->second.maListeners); 145*95a18594SAndre Fischer const ListenerContainer::iterator iListener ( 146*95a18594SAndre Fischer ::std::find(rContainer.begin(), rContainer.end(), rxListener)); 14722de8995SAndre Fischer if (iListener != rContainer.end()) 148b9e67834SAndre Fischer { 14922de8995SAndre Fischer rContainer.erase(iListener); 150b9e67834SAndre Fischer 151b9e67834SAndre Fischer // Remove the listener container as well when its last 152b9e67834SAndre Fischer // listener was just removed. This prevents us from 153b9e67834SAndre Fischer // holding the focus alive. 154b9e67834SAndre Fischer if (rContainer.empty()) 155*95a18594SAndre Fischer maListeners.erase(iDescriptor); 156b9e67834SAndre Fischer } 15722de8995SAndre Fischer } 15822de8995SAndre Fischer 15922de8995SAndre Fischer } 16022de8995SAndre Fischer 16122de8995SAndre Fischer 16222de8995SAndre Fischer 16322de8995SAndre Fischer 16422de8995SAndre Fischer void SAL_CALL ContextChangeEventMultiplexer::removeAllContextChangeEventListeners ( 16522de8995SAndre Fischer const cssu::Reference<css::ui::XContextChangeEventListener>& rxListener) 16622de8995SAndre Fischer throw(cssu::RuntimeException,cssl::IllegalArgumentException) 16722de8995SAndre Fischer { 16822de8995SAndre Fischer if ( ! rxListener.is()) 169*95a18594SAndre Fischer throw cssl::IllegalArgumentException( 170*95a18594SAndre Fischer A2S("can not remove an empty reference"), 171*95a18594SAndre Fischer static_cast<XWeak*>(this), 0); 17222de8995SAndre Fischer 173b9e67834SAndre Fischer ::std::vector<cssu::Reference<cssu::XInterface> > aContainersToRemove; 17422de8995SAndre Fischer for (ListenerMap::iterator 17522de8995SAndre Fischer iContainer(maListeners.begin()), 17622de8995SAndre Fischer iEnd(maListeners.end()); 17722de8995SAndre Fischer iContainer!=iEnd; 17822de8995SAndre Fischer ++iContainer) 17922de8995SAndre Fischer { 180*95a18594SAndre Fischer const ListenerContainer::iterator iListener ( 181*95a18594SAndre Fischer ::std::find(iContainer->second.maListeners.begin(), iContainer->second.maListeners.end(), rxListener)); 182*95a18594SAndre Fischer if (iListener != iContainer->second.maListeners.end()) 183b9e67834SAndre Fischer { 184*95a18594SAndre Fischer iContainer->second.maListeners.erase(iListener); 185b9e67834SAndre Fischer 186b9e67834SAndre Fischer // When we just removed the last listener then mark the 187b9e67834SAndre Fischer // container as to be removed. 188*95a18594SAndre Fischer if (iContainer->second.maListeners.empty()) 189b9e67834SAndre Fischer aContainersToRemove.push_back(iContainer->first); 190b9e67834SAndre Fischer } 191b9e67834SAndre Fischer } 192b9e67834SAndre Fischer 193b9e67834SAndre Fischer for (::std::vector<cssu::Reference<cssu::XInterface> >::iterator 194b9e67834SAndre Fischer iFocus(aContainersToRemove.begin()), 195b9e67834SAndre Fischer iEnd(aContainersToRemove.end()); 196b9e67834SAndre Fischer iFocus!=iEnd; 197b9e67834SAndre Fischer ++iFocus) 198b9e67834SAndre Fischer { 199b9e67834SAndre Fischer maListeners.erase(*iFocus); 20022de8995SAndre Fischer } 20122de8995SAndre Fischer } 20222de8995SAndre Fischer 20322de8995SAndre Fischer 20422de8995SAndre Fischer 20522de8995SAndre Fischer 20622de8995SAndre Fischer void SAL_CALL ContextChangeEventMultiplexer::broadcastContextChangeEvent ( 20722de8995SAndre Fischer const css::ui::ContextChangeEventObject& rEventObject, 20822de8995SAndre Fischer const cssu::Reference<cssu::XInterface>& rxEventFocus) 20922de8995SAndre Fischer throw(cssu::RuntimeException) 21022de8995SAndre Fischer { 211*95a18594SAndre Fischer // Remember the current context. 212*95a18594SAndre Fischer if (rxEventFocus.is()) 213*95a18594SAndre Fischer { 214*95a18594SAndre Fischer ListenerMap::iterator iDescriptor (maListeners.find(rxEventFocus)); 215*95a18594SAndre Fischer if (iDescriptor != maListeners.end()) 216*95a18594SAndre Fischer { 217*95a18594SAndre Fischer iDescriptor->second.msCurrentApplicationName = rEventObject.ApplicationName; 218*95a18594SAndre Fischer iDescriptor->second.msCurrentContextName = rEventObject.ContextName; 219*95a18594SAndre Fischer } 220*95a18594SAndre Fischer } 221*95a18594SAndre Fischer 22222de8995SAndre Fischer BroadcastEventToSingleContainer(rEventObject, rxEventFocus); 22322de8995SAndre Fischer if (rxEventFocus.is()) 22422de8995SAndre Fischer BroadcastEventToSingleContainer(rEventObject, NULL); 22522de8995SAndre Fischer } 22622de8995SAndre Fischer 22722de8995SAndre Fischer 22822de8995SAndre Fischer 22922de8995SAndre Fischer 23022de8995SAndre Fischer void ContextChangeEventMultiplexer::BroadcastEventToSingleContainer ( 23122de8995SAndre Fischer const css::ui::ContextChangeEventObject& rEventObject, 23222de8995SAndre Fischer const cssu::Reference<cssu::XInterface>& rxEventFocus) 23322de8995SAndre Fischer { 234*95a18594SAndre Fischer ListenerMap::iterator iDescriptor (maListeners.find(rxEventFocus)); 235*95a18594SAndre Fischer if (iDescriptor != maListeners.end()) 23622de8995SAndre Fischer { 23722de8995SAndre Fischer // Create a copy of the listener container to avoid problems 23822de8995SAndre Fischer // when one of the called listeners calls add... or remove... 239*95a18594SAndre Fischer ListenerContainer aContainer (iDescriptor->second.maListeners); 24022de8995SAndre Fischer for (ListenerContainer::const_iterator 24122de8995SAndre Fischer iListener(aContainer.begin()), 24222de8995SAndre Fischer iEnd(aContainer.end()); 24322de8995SAndre Fischer iListener!=iEnd; 24422de8995SAndre Fischer ++iListener) 24522de8995SAndre Fischer { 24622de8995SAndre Fischer (*iListener)->notifyContextChangeEvent(rEventObject); 24722de8995SAndre Fischer } 24822de8995SAndre Fischer } 24922de8995SAndre Fischer } 25022de8995SAndre Fischer 25122de8995SAndre Fischer 25222de8995SAndre Fischer 25322de8995SAndre Fischer 25422de8995SAndre Fischer // XSingleComponentFactory 25522de8995SAndre Fischer 25622de8995SAndre Fischer cssu::Reference<cssu::XInterface> SAL_CALL ContextChangeEventMultiplexer::createInstanceWithContext ( 25722de8995SAndre Fischer const cssu::Reference<cssu::XComponentContext>& rxContext) 25822de8995SAndre Fischer throw (cssu::Exception, cssu::RuntimeException) 25922de8995SAndre Fischer { 26022de8995SAndre Fischer (void)rxContext; 26122de8995SAndre Fischer return cssu::Reference<cssu::XInterface>(); 26222de8995SAndre Fischer } 26322de8995SAndre Fischer 26422de8995SAndre Fischer 26522de8995SAndre Fischer 26622de8995SAndre Fischer 26722de8995SAndre Fischer cssu::Reference<cssu::XInterface > SAL_CALL ContextChangeEventMultiplexer::createInstanceWithArgumentsAndContext ( 26822de8995SAndre Fischer const cssu::Sequence<cssu::Any>& rArguments, 26922de8995SAndre Fischer const cssu::Reference<cssu::XComponentContext>& rxContext) 27022de8995SAndre Fischer throw (cssu::Exception, cssu::RuntimeException) 27122de8995SAndre Fischer { 27222de8995SAndre Fischer (void)rArguments; 27322de8995SAndre Fischer (void)rxContext; 27422de8995SAndre Fischer return cssu::Reference<cssu::XInterface>(); 27522de8995SAndre Fischer } 27622de8995SAndre Fischer 27722de8995SAndre Fischer 27822de8995SAndre Fischer 27922de8995SAndre Fischer 28022de8995SAndre Fischer // XServiceInfo 28122de8995SAndre Fischer 28222de8995SAndre Fischer ::rtl::OUString SAL_CALL ContextChangeEventMultiplexer::getImplementationName (void) 28322de8995SAndre Fischer throw(cssu::RuntimeException) 28422de8995SAndre Fischer { 28522de8995SAndre Fischer return impl_getStaticImplementationName(); 28622de8995SAndre Fischer } 28722de8995SAndre Fischer 28822de8995SAndre Fischer 28922de8995SAndre Fischer 29022de8995SAndre Fischer 29122de8995SAndre Fischer 29222de8995SAndre Fischer sal_Bool SAL_CALL ContextChangeEventMultiplexer::supportsService ( 29322de8995SAndre Fischer const ::rtl::OUString& rsServiceName) 29422de8995SAndre Fischer throw (cssu::RuntimeException) 29522de8995SAndre Fischer { 29622de8995SAndre Fischer return ::comphelper::findValue(static_GetSupportedServiceNames(), rsServiceName, sal_True).getLength() != 0; 29722de8995SAndre Fischer } 29822de8995SAndre Fischer 29922de8995SAndre Fischer 30022de8995SAndre Fischer 30122de8995SAndre Fischer 30222de8995SAndre Fischer cssu::Sequence<OUString> SAL_CALL ContextChangeEventMultiplexer::getSupportedServiceNames (void) 30322de8995SAndre Fischer throw (cssu::RuntimeException) 30422de8995SAndre Fischer { 30522de8995SAndre Fischer return static_GetSupportedServiceNames(); 30622de8995SAndre Fischer } 30722de8995SAndre Fischer 30822de8995SAndre Fischer 30922de8995SAndre Fischer 31022de8995SAndre Fischer 31122de8995SAndre Fischer // Local and static methods. 31222de8995SAndre Fischer 31322de8995SAndre Fischer OUString SAL_CALL ContextChangeEventMultiplexer::impl_getStaticImplementationName (void) 31422de8995SAndre Fischer { 31522de8995SAndre Fischer return A2S(IMPLEMENTATION_NAME); 31622de8995SAndre Fischer } 31722de8995SAndre Fischer 31822de8995SAndre Fischer 31922de8995SAndre Fischer 32022de8995SAndre Fischer 32122de8995SAndre Fischer cssu::Sequence<OUString> SAL_CALL ContextChangeEventMultiplexer::static_GetSupportedServiceNames (void) 32222de8995SAndre Fischer { 32322de8995SAndre Fischer cssu::Sequence<OUString> aServiceNames (2); 32422de8995SAndre Fischer aServiceNames[0] = A2S(SERVICE_NAME); 32522de8995SAndre Fischer aServiceNames[1] = A2S(SINGLETON_NAME); 32622de8995SAndre Fischer return aServiceNames; 32722de8995SAndre Fischer } 32822de8995SAndre Fischer 32922de8995SAndre Fischer 33022de8995SAndre Fischer 33122de8995SAndre Fischer 33222de8995SAndre Fischer cssu::Reference<cssu::XInterface> ContextChangeEventMultiplexer::impl_createFactory ( 33322de8995SAndre Fischer const cssu::Reference<cssl::XMultiServiceFactory>& rxServiceManager) 33422de8995SAndre Fischer { 33522de8995SAndre Fischer (void)rxServiceManager; 33622de8995SAndre Fischer return cppu::createSingleComponentFactory( 33722de8995SAndre Fischer ContextChangeEventMultiplexer::static_CreateInstance, 33822de8995SAndre Fischer ContextChangeEventMultiplexer::impl_getStaticImplementationName(), 33922de8995SAndre Fischer ContextChangeEventMultiplexer::static_GetSupportedServiceNames() 34022de8995SAndre Fischer ); 34122de8995SAndre Fischer } 34222de8995SAndre Fischer 34322de8995SAndre Fischer 34422de8995SAndre Fischer 34522de8995SAndre Fischer 34622de8995SAndre Fischer cssu::Reference<cssu::XInterface> SAL_CALL ContextChangeEventMultiplexer::static_CreateInstance ( 34722de8995SAndre Fischer const cssu::Reference<cssu::XComponentContext>& rxComponentContext) 34822de8995SAndre Fischer throw (cssu::Exception) 34922de8995SAndre Fischer { 35022de8995SAndre Fischer ContextChangeEventMultiplexer* pObject = new ContextChangeEventMultiplexer(rxComponentContext); 35122de8995SAndre Fischer cssu::Reference<cssu::XInterface> xService (static_cast<XWeak*>(pObject), cssu::UNO_QUERY); 35222de8995SAndre Fischer return xService; 35322de8995SAndre Fischer } 35422de8995SAndre Fischer 35522de8995SAndre Fischer } // end of namespace framework 356