1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
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
),
43 void ConfigurationControllerBroadcaster::AddListener(
44 const Reference
<XConfigurationChangeListener
>& rxListener
,
45 const OUString
& rsEventType
,
48 if ( ! rxListener
.is())
49 throw lang::IllegalArgumentException("invalid listener",
50 mxConfigurationController
,
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
,
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
);
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
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())
181 // When the first vector is empty then remove it from the map.
182 if (iMap
->second
.empty())
184 maListenerMap
.erase(iMap
);
189 Reference
<lang::XEventListener
> xListener (
190 iMap
->second
.front().mxListener
, UNO_QUERY
);
193 // Tell the listener that the configuration controller is
194 // being disposed and remove the listener (for all event
198 RemoveListener(iMap
->second
.front().mxListener
);
199 xListener
->disposing(aEvent
);
201 catch (const RuntimeException
&)
203 DBG_UNHANDLED_EXCEPTION();
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: */