bump product version to 4.1.6.2
[LibreOffice.git] / sd / source / ui / framework / configuration / ConfigurationControllerBroadcaster.cxx
bloba5640f85fbb0eb61d9595bee59d80620ee9aa25d
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 .
21 #include "ConfigurationControllerBroadcaster.hxx"
22 #include <com/sun/star/lang/IllegalArgumentException.hpp>
23 #include <com/sun/star/lang/DisposedException.hpp>
24 #include <tools/debug.hxx>
25 #include <tools/diagnose_ex.h>
27 using namespace ::com::sun::star;
28 using namespace ::com::sun::star::uno;
29 using namespace ::com::sun::star::drawing::framework;
31 namespace sd { namespace framework {
33 ConfigurationControllerBroadcaster::ConfigurationControllerBroadcaster (
34 const Reference<XConfigurationController>& rxController)
35 : mxConfigurationController(rxController),
36 maListenerMap()
43 void ConfigurationControllerBroadcaster::AddListener(
44 const Reference<XConfigurationChangeListener>& rxListener,
45 const OUString& rsEventType,
46 const Any& rUserData)
48 if ( ! rxListener.is())
49 throw lang::IllegalArgumentException("invalid listener",
50 mxConfigurationController,
51 0);
53 if (maListenerMap.find(rsEventType) == maListenerMap.end())
54 maListenerMap[rsEventType] = ListenerList();
55 ListenerDescriptor aDescriptor;
56 aDescriptor.mxListener = rxListener;
57 aDescriptor.maUserData = rUserData;
58 maListenerMap[rsEventType].push_back(aDescriptor);
64 void ConfigurationControllerBroadcaster::RemoveListener(
65 const Reference<XConfigurationChangeListener>& rxListener)
67 if ( ! rxListener.is())
68 throw lang::IllegalArgumentException("invalid listener",
69 mxConfigurationController,
70 0);
72 ListenerMap::iterator iMap;
73 ListenerList::iterator iList;
74 for (iMap=maListenerMap.begin(); iMap!=maListenerMap.end(); ++iMap)
76 for (iList=iMap->second.begin(); iList!=iMap->second.end(); ++iList)
78 if (iList->mxListener == rxListener)
80 iMap->second.erase(iList);
81 break;
90 void ConfigurationControllerBroadcaster::NotifyListeners (
91 const ListenerList& rList,
92 const ConfigurationChangeEvent& rEvent)
94 // Create a local copy of the event in which the user data is modified
95 // for every listener.
96 ConfigurationChangeEvent aEvent (rEvent);
98 ListenerList::const_iterator iListener;
99 for (iListener=rList.begin(); iListener!=rList.end(); ++iListener)
103 aEvent.UserData = iListener->maUserData;
104 iListener->mxListener->notifyConfigurationChange(aEvent);
106 catch (const lang::DisposedException& rException)
108 // When the exception comes from the listener itself then
109 // unregister it.
110 if (rException.Context == iListener->mxListener)
111 RemoveListener(iListener->mxListener);
113 catch (const RuntimeException&)
115 DBG_UNHANDLED_EXCEPTION();
123 void ConfigurationControllerBroadcaster::NotifyListeners (const ConfigurationChangeEvent& rEvent)
125 // Notify the specialized listeners.
126 ListenerMap::const_iterator iMap (maListenerMap.find(rEvent.Type));
127 if (iMap != maListenerMap.end())
129 // Create a local list of the listeners to avoid problems with
130 // concurrent changes and to be able to remove disposed listeners.
131 ListenerList aList (iMap->second.begin(), iMap->second.end());
132 NotifyListeners(aList,rEvent);
135 // Notify the universal listeners.
136 iMap = maListenerMap.find(OUString());
137 if (iMap != maListenerMap.end())
139 // Create a local list of the listeners to avoid problems with
140 // concurrent changes and to be able to remove disposed listeners.
141 ListenerList aList (iMap->second.begin(), iMap->second.end());
142 NotifyListeners(aList,rEvent);
149 void ConfigurationControllerBroadcaster::NotifyListeners (
150 const OUString& rsEventType,
151 const Reference<XResourceId>& rxResourceId,
152 const Reference<XResource>& rxResourceObject)
154 ConfigurationChangeEvent aEvent;
155 aEvent.Type = rsEventType;
156 aEvent.ResourceId = rxResourceId;
157 aEvent.ResourceObject = rxResourceObject;
160 NotifyListeners(aEvent);
162 catch (const lang::DisposedException&)
171 void ConfigurationControllerBroadcaster::DisposeAndClear (void)
173 lang::EventObject aEvent;
174 aEvent.Source = mxConfigurationController;
175 while (!maListenerMap.empty())
177 ListenerMap::iterator iMap (maListenerMap.begin());
178 if (iMap == maListenerMap.end())
179 break;
181 // When the first vector is empty then remove it from the map.
182 if (iMap->second.empty())
184 maListenerMap.erase(iMap);
185 continue;
187 else
189 Reference<lang::XEventListener> xListener (
190 iMap->second.front().mxListener, UNO_QUERY);
191 if (xListener.is())
193 // Tell the listener that the configuration controller is
194 // being disposed and remove the listener (for all event
195 // types).
198 RemoveListener(iMap->second.front().mxListener);
199 xListener->disposing(aEvent);
201 catch (const RuntimeException&)
203 DBG_UNHANDLED_EXCEPTION();
206 else
208 // Remove just this reference to the listener.
209 iMap->second.erase(iMap->second.begin());
218 } } // end of namespace sd::framework
220 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */