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 .
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
),
38 void ConfigurationControllerBroadcaster::AddListener(
39 const Reference
<XConfigurationChangeListener
>& rxListener
,
40 const OUString
& rsEventType
,
43 if ( ! rxListener
.is())
44 throw lang::IllegalArgumentException("invalid listener",
45 mxConfigurationController
,
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
,
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
);
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
)
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
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())
160 // When the first vector is empty then remove it from the map.
161 if (iMap
->second
.empty())
163 maListenerMap
.erase(iMap
);
168 Reference
<lang::XEventListener
> xListener (
169 iMap
->second
.front().mxListener
, UNO_QUERY
);
172 // Tell the listener that the configuration controller is
173 // being disposed and remove the listener (for all event
177 RemoveListener(iMap
->second
.front().mxListener
);
178 xListener
->disposing(aEvent
);
180 catch (const RuntimeException
&)
182 DBG_UNHANDLED_EXCEPTION();
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: */