bump product version to 5.0.4.1
[LibreOffice.git] / sd / source / ui / framework / configuration / ConfigurationControllerBroadcaster.cxx
blob5ee7f9d157802759ba21c8be58d1378dbd549c3f
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include "ConfigurationControllerBroadcaster.hxx"
21 #include <com/sun/star/lang/IllegalArgumentException.hpp>
22 #include <com/sun/star/lang/DisposedException.hpp>
23 #include <tools/diagnose_ex.h>
25 using namespace ::com::sun::star;
26 using namespace ::com::sun::star::uno;
27 using namespace ::com::sun::star::drawing::framework;
29 namespace sd { namespace framework {
31 ConfigurationControllerBroadcaster::ConfigurationControllerBroadcaster (
32 const Reference<XConfigurationController>& rxController)
33 : mxConfigurationController(rxController),
34 maListenerMap()
38 void ConfigurationControllerBroadcaster::AddListener(
39 const Reference<XConfigurationChangeListener>& rxListener,
40 const OUString& rsEventType,
41 const Any& rUserData)
43 if ( ! rxListener.is())
44 throw lang::IllegalArgumentException("invalid listener",
45 mxConfigurationController,
46 0);
48 if (maListenerMap.find(rsEventType) == maListenerMap.end())
49 maListenerMap[rsEventType] = ListenerList();
50 ListenerDescriptor aDescriptor;
51 aDescriptor.mxListener = rxListener;
52 aDescriptor.maUserData = rUserData;
53 maListenerMap[rsEventType].push_back(aDescriptor);
56 void ConfigurationControllerBroadcaster::RemoveListener(
57 const Reference<XConfigurationChangeListener>& rxListener)
59 if ( ! rxListener.is())
60 throw lang::IllegalArgumentException("invalid listener",
61 mxConfigurationController,
62 0);
64 ListenerMap::iterator iMap;
65 ListenerList::iterator iList;
66 for (iMap=maListenerMap.begin(); iMap!=maListenerMap.end(); ++iMap)
68 for (iList=iMap->second.begin(); iList!=iMap->second.end(); ++iList)
70 if (iList->mxListener == rxListener)
72 iMap->second.erase(iList);
73 break;
79 void ConfigurationControllerBroadcaster::NotifyListeners (
80 const ListenerList& rList,
81 const ConfigurationChangeEvent& rEvent)
83 // Create a local copy of the event in which the user data is modified
84 // for every listener.
85 ConfigurationChangeEvent aEvent (rEvent);
87 ListenerList::const_iterator iListener;
88 for (iListener=rList.begin(); iListener!=rList.end(); ++iListener)
90 try
92 aEvent.UserData = iListener->maUserData;
93 iListener->mxListener->notifyConfigurationChange(aEvent);
95 catch (const lang::DisposedException& rException)
97 // When the exception comes from the listener itself then
98 // unregister it.
99 if (rException.Context == iListener->mxListener)
100 RemoveListener(iListener->mxListener);
102 catch (const RuntimeException&)
104 DBG_UNHANDLED_EXCEPTION();
109 void ConfigurationControllerBroadcaster::NotifyListeners (const ConfigurationChangeEvent& rEvent)
111 // Notify the specialized listeners.
112 ListenerMap::const_iterator iMap (maListenerMap.find(rEvent.Type));
113 if (iMap != maListenerMap.end())
115 // Create a local list of the listeners to avoid problems with
116 // concurrent changes and to be able to remove disposed listeners.
117 ListenerList aList (iMap->second.begin(), iMap->second.end());
118 NotifyListeners(aList,rEvent);
121 // Notify the universal listeners.
122 iMap = maListenerMap.find(OUString());
123 if (iMap != maListenerMap.end())
125 // Create a local list of the listeners to avoid problems with
126 // concurrent changes and to be able to remove disposed listeners.
127 ListenerList aList (iMap->second.begin(), iMap->second.end());
128 NotifyListeners(aList,rEvent);
132 void ConfigurationControllerBroadcaster::NotifyListeners (
133 const OUString& rsEventType,
134 const Reference<XResourceId>& rxResourceId,
135 const Reference<XResource>& rxResourceObject)
137 ConfigurationChangeEvent aEvent;
138 aEvent.Type = rsEventType;
139 aEvent.ResourceId = rxResourceId;
140 aEvent.ResourceObject = rxResourceObject;
143 NotifyListeners(aEvent);
145 catch (const lang::DisposedException&)
150 void ConfigurationControllerBroadcaster::DisposeAndClear()
152 lang::EventObject aEvent;
153 aEvent.Source = mxConfigurationController;
154 while (!maListenerMap.empty())
156 ListenerMap::iterator iMap (maListenerMap.begin());
157 if (iMap == maListenerMap.end())
158 break;
160 // When the first vector is empty then remove it from the map.
161 if (iMap->second.empty())
163 maListenerMap.erase(iMap);
164 continue;
166 else
168 Reference<lang::XEventListener> xListener (
169 iMap->second.front().mxListener, UNO_QUERY);
170 if (xListener.is())
172 // Tell the listener that the configuration controller is
173 // being disposed and remove the listener (for all event
174 // types).
177 RemoveListener(iMap->second.front().mxListener);
178 xListener->disposing(aEvent);
180 catch (const RuntimeException&)
182 DBG_UNHANDLED_EXCEPTION();
185 else
187 // Remove just this reference to the listener.
188 iMap->second.erase(iMap->second.begin());
194 } } // end of namespace sd::framework
196 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */