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