1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_sd.hxx"
30 
31 #include "EventMultiplexer.hxx"
32 
33 #include "MutexOwner.hxx"
34 #include "ViewShellBase.hxx"
35 #include "drawdoc.hxx"
36 #include "DrawController.hxx"
37 #include "SlideSorterViewShell.hxx"
38 #include "framework/FrameworkHelper.hxx"
39 
40 #include <com/sun/star/beans/XPropertySet.hpp>
41 #include <com/sun/star/frame/XFrame.hpp>
42 #include <com/sun/star/lang/DisposedException.hpp>
43 #include <com/sun/star/drawing/framework/XConfigurationChangeListener.hpp>
44 #include <cppuhelper/weak.hxx>
45 #include <cppuhelper/compbase4.hxx>
46 #include <sfx2/viewfrm.hxx>
47 
48 using namespace ::com::sun::star;
49 using namespace ::com::sun::star::lang;
50 using namespace ::com::sun::star::uno;
51 using namespace ::com::sun::star::drawing::framework;
52 
53 using ::rtl::OUString;
54 using ::sd::framework::FrameworkHelper;
55 
56 class SdDrawDocument;
57 
58 namespace {
59 static const sal_Int32 ResourceActivationEvent = 0;
60 static const sal_Int32 ResourceDeactivationEvent = 1;
61 static const sal_Int32 ConfigurationUpdateEvent = 2;
62 }
63 
64 namespace sd { namespace tools {
65 
66 typedef cppu::WeakComponentImplHelper4<
67       ::com::sun::star::beans::XPropertyChangeListener,
68       ::com::sun::star::frame::XFrameActionListener,
69       ::com::sun::star::view::XSelectionChangeListener,
70       ::com::sun::star::drawing::framework::XConfigurationChangeListener
71     > EventMultiplexerImplementationInterfaceBase;
72 
73 class EventMultiplexer::Implementation
74     : protected MutexOwner,
75       public EventMultiplexerImplementationInterfaceBase,
76       public SfxListener
77 {
78 public:
79     Implementation (ViewShellBase& rBase);
80     ~Implementation (void);
81 
82     void AddEventListener (
83         Link& rCallback,
84         EventMultiplexerEvent::EventId aEventTypes);
85 
86     void RemoveEventListener (
87         Link& rCallback,
88         EventMultiplexerEvent::EventId aEventTypes);
89 
90 	void CallListeners (EventMultiplexerEvent& rEvent);
91 
92 	ViewShellBase& GetViewShellBase() const { return mrBase; }
93 
94     //===== lang::XEventListener ==============================================
95     virtual void SAL_CALL
96         disposing (const ::com::sun::star::lang::EventObject& rEventObject)
97         throw (::com::sun::star::uno::RuntimeException);
98 
99 
100     //===== beans::XPropertySetListener =======================================
101     virtual void SAL_CALL
102         propertyChange (
103             const com::sun::star::beans::PropertyChangeEvent& rEvent)
104         throw (::com::sun::star::uno::RuntimeException);
105 
106     //===== view::XSelectionChangeListener ====================================
107     virtual void SAL_CALL
108         selectionChanged (
109             const com::sun::star::lang::EventObject& rEvent)
110         throw (::com::sun::star::uno::RuntimeException);
111 
112     //===== frame::XFrameActionListener  ======================================
113     /** For certain actions the listener connects to a new controller of the
114         frame it is listening to.  This usually happens when the view shell
115         in the center pane is replaced by another view shell.
116     */
117     virtual void SAL_CALL
118         frameAction (const ::com::sun::star::frame::FrameActionEvent& rEvent)
119         throw (::com::sun::star::uno::RuntimeException);
120 
121     //===== drawing::framework::XConfigurationChangeListener ==================
122     virtual void SAL_CALL
123         notifyConfigurationChange (
124             const ::com::sun::star::drawing::framework::ConfigurationChangeEvent& rEvent)
125         throw (::com::sun::star::uno::RuntimeException);
126 
127 
128     virtual void SAL_CALL disposing (void);
129 
130 protected:
131     virtual void Notify (
132         SfxBroadcaster& rBroadcaster,
133         const SfxHint& rHint);
134 
135 private:
136     ViewShellBase& mrBase;
137     typedef ::std::pair<Link,EventMultiplexerEvent::EventId> ListenerDescriptor;
138     typedef ::std::vector<ListenerDescriptor> ListenerList;
139     ListenerList maListeners;
140 
141     /// Remember whether we are listening to the UNO controller.
142     bool mbListeningToController;
143     /// Remember whether we are listening to the frame.
144     bool mbListeningToFrame;
145 
146     ::com::sun::star::uno::WeakReference<
147         ::com::sun::star::frame::XController> mxControllerWeak;
148     ::com::sun::star::uno::WeakReference<
149         ::com::sun::star::frame::XFrame> mxFrameWeak;
150     ::com::sun::star::uno::WeakReference<
151         ::com::sun::star::view::XSelectionSupplier> mxSlideSorterSelectionWeak;
152     SdDrawDocument* mpDocument;
153     ::com::sun::star::uno::WeakReference<
154         ::com::sun::star::drawing::framework::XConfigurationController>
155         mxConfigurationControllerWeak;
156 
157     static const ::rtl::OUString msCurrentPagePropertyName;
158     static const ::rtl::OUString msEditModePropertyName;
159 
160     void ReleaseListeners (void);
161 
162     void ConnectToController (void);
163     void DisconnectFromController (void);
164 
165     void CallListeners (
166         EventMultiplexerEvent::EventId eId,
167         void* pUserData = NULL);
168 
169     /** This method throws a DisposedException when the object has already been
170         disposed.
171     */
172     void ThrowIfDisposed (void)
173         throw (::com::sun::star::lang::DisposedException);
174 
175     DECL_LINK(SlideSorterSelectionChangeListener, void*);
176 };
177 
178 
179 const ::rtl::OUString EventMultiplexer::Implementation::msCurrentPagePropertyName (
180     RTL_CONSTASCII_USTRINGPARAM("CurrentPage"));
181 const ::rtl::OUString EventMultiplexer::Implementation::msEditModePropertyName (
182     RTL_CONSTASCII_USTRINGPARAM("IsMasterPageMode"));
183 
184 
185 //===== EventMultiplexer ======================================================
186 
187 EventMultiplexer::EventMultiplexer (ViewShellBase& rBase)
188     : mpImpl (new EventMultiplexer::Implementation(rBase))
189 {
190     mpImpl->acquire();
191 }
192 
193 
194 
195 
196 EventMultiplexer::~EventMultiplexer (void)
197 {
198     try
199     {
200         mpImpl->dispose();
201         // Now we call release twice.  One decreases the use count of the
202         // implementation object (if all goes well to zero and thus deletes
203         // it.)  The other releases the auto_ptr and prevents the
204         // implementation object from being deleted a second time.
205         mpImpl->release();
206         mpImpl.release();
207     }
208     catch (RuntimeException aException)
209     {
210     }
211     catch (Exception aException)
212     {
213     }
214 }
215 
216 
217 
218 
219 void EventMultiplexer::AddEventListener (
220     Link& rCallback,
221     EventMultiplexerEvent::EventId aEventTypes)
222 {
223     mpImpl->AddEventListener (rCallback, aEventTypes);
224 }
225 
226 
227 
228 
229 void EventMultiplexer::RemoveEventListener (
230     Link& rCallback,
231     EventMultiplexerEvent::EventId aEventTypes)
232 {
233     mpImpl->RemoveEventListener (rCallback, aEventTypes);
234 }
235 
236 
237 
238 
239 void EventMultiplexer::MultiplexEvent(
240     EventMultiplexerEvent::EventId eEventId,
241     void* pUserData )
242 {
243 	EventMultiplexerEvent aEvent (mpImpl->GetViewShellBase(), eEventId, pUserData);
244     mpImpl->CallListeners(aEvent);
245 }
246 
247 
248 
249 
250 //===== EventMultiplexer::Implementation ======================================
251 
252 EventMultiplexer::Implementation::Implementation (ViewShellBase& rBase)
253     : MutexOwner(),
254       EventMultiplexerImplementationInterfaceBase(maMutex),
255       SfxListener(),
256       mrBase (rBase),
257       mbListeningToController (false),
258       mbListeningToFrame (false),
259       mxControllerWeak(NULL),
260       mxFrameWeak(NULL),
261       mxSlideSorterSelectionWeak(NULL),
262       mpDocument(NULL),
263       mxConfigurationControllerWeak()
264 {
265     // Connect to the frame to listen for controllers being exchanged.
266     // Listen to changes of certain properties.
267     Reference<frame::XFrame> xFrame (
268         mrBase.GetFrame()->GetTopFrame().GetFrameInterface(),
269         uno::UNO_QUERY);
270     mxFrameWeak = xFrame;
271     if (xFrame.is())
272     {
273         xFrame->addFrameActionListener (
274             Reference<frame::XFrameActionListener>(
275                static_cast<XWeak*>(this), UNO_QUERY));
276         mbListeningToFrame = true;
277     }
278 
279     // Connect to the current controller.
280     ConnectToController ();
281 
282     // Listen for document changes.
283     mpDocument = mrBase.GetDocument();
284     if (mpDocument != NULL)
285         StartListening (*mpDocument);
286 
287     // Listen for configuration changes.
288     Reference<XControllerManager> xControllerManager (
289         Reference<XWeak>(&mrBase.GetDrawController()), UNO_QUERY);
290     if (xControllerManager.is())
291     {
292         Reference<XConfigurationController> xConfigurationController (
293             xControllerManager->getConfigurationController());
294         mxConfigurationControllerWeak = xConfigurationController;
295         if (xConfigurationController.is())
296         {
297             Reference<XComponent> xComponent (xConfigurationController, UNO_QUERY);
298             if (xComponent.is())
299                 xComponent->addEventListener(static_cast<beans::XPropertyChangeListener*>(this));
300 
301             xConfigurationController->addConfigurationChangeListener(
302                 this,
303                 FrameworkHelper::msResourceActivationEvent,
304                 makeAny(ResourceActivationEvent));
305             xConfigurationController->addConfigurationChangeListener(
306                 this,
307                 FrameworkHelper::msResourceDeactivationEvent,
308                 makeAny(ResourceDeactivationEvent));
309             xConfigurationController->addConfigurationChangeListener(
310                 this,
311                 FrameworkHelper::msConfigurationUpdateEndEvent,
312                 makeAny(ConfigurationUpdateEvent));
313         }
314     }
315 }
316 
317 
318 
319 
320 EventMultiplexer::Implementation::~Implementation (void)
321 {
322 	DBG_ASSERT( !mbListeningToFrame,
323         "sd::EventMultiplexer::Implementation::~Implementation(), disposing was not called!" );
324 }
325 
326 
327 
328 
329 void EventMultiplexer::Implementation::ReleaseListeners (void)
330 {
331     if (mbListeningToFrame)
332     {
333         mbListeningToFrame = false;
334 
335         // Stop listening for changes of certain properties.
336         Reference<frame::XFrame> xFrame (mxFrameWeak);
337         if (xFrame.is())
338         {
339             xFrame->removeFrameActionListener (
340                 Reference<frame::XFrameActionListener>(
341                     static_cast<XWeak*>(this), UNO_QUERY));
342         }
343     }
344 
345     DisconnectFromController ();
346 
347     if (mpDocument != NULL)
348     {
349         EndListening (*mpDocument);
350         mpDocument = NULL;
351     }
352 
353     // Stop listening for configuration changes.
354     Reference<XConfigurationController> xConfigurationController (mxConfigurationControllerWeak);
355     if (xConfigurationController.is())
356     {
357         Reference<XComponent> xComponent (xConfigurationController, UNO_QUERY);
358         if (xComponent.is())
359             xComponent->removeEventListener(static_cast<beans::XPropertyChangeListener*>(this));
360 
361         xConfigurationController->removeConfigurationChangeListener(this);
362     }
363 }
364 
365 
366 
367 
368 void EventMultiplexer::Implementation::AddEventListener (
369     Link& rCallback,
370     EventMultiplexerEvent::EventId aEventTypes)
371 {
372     ListenerList::iterator iListener (maListeners.begin());
373     ListenerList::const_iterator iEnd (maListeners.end());
374     for (;iListener!=iEnd; ++iListener)
375         if (iListener->first == rCallback)
376             break;
377     if (iListener != maListeners.end())
378     {
379         // Listener exists.  Update its event type set.
380         iListener->second |= aEventTypes;
381     }
382     else
383     {
384         maListeners.push_back (ListenerDescriptor(rCallback,aEventTypes));
385     }
386 }
387 
388 
389 
390 
391 void EventMultiplexer::Implementation::RemoveEventListener (
392     Link& rCallback,
393     EventMultiplexerEvent::EventId aEventTypes)
394 {
395     ListenerList::iterator iListener (maListeners.begin());
396     ListenerList::const_iterator iEnd (maListeners.end());
397     for (;iListener!=iEnd; ++iListener)
398         if (iListener->first == rCallback)
399             break;
400     if (iListener != maListeners.end())
401     {
402         // Update the event type set.
403         iListener->second &= ~aEventTypes;
404         // When no events remain in the set then remove the listener.
405         if (iListener->second == EID_EMPTY_SET)
406             maListeners.erase (iListener);
407     }
408 }
409 
410 
411 
412 
413 void EventMultiplexer::Implementation::ConnectToController (void)
414 {
415     // Just in case that we missed some event we now disconnect from the old
416     // controller.
417     DisconnectFromController ();
418 
419     // Register at the controller of the main view shell.
420 
421     // We have to store a (weak) reference to the controller so that we can
422     // unregister without having to ask the mrBase member (which at that
423     // time may be destroyed.)
424     Reference<frame::XController> xController = mrBase.GetController();
425     mxControllerWeak = mrBase.GetController();
426 
427     try
428     {
429         // Listen for disposing events.
430         Reference<lang::XComponent> xComponent (xController, UNO_QUERY);
431         if (xComponent.is())
432         {
433             xComponent->addEventListener (
434                 Reference<lang::XEventListener>(
435                     static_cast<XWeak*>(this), UNO_QUERY));
436             mbListeningToController = true;
437         }
438 
439         // Listen to changes of certain properties.
440         Reference<beans::XPropertySet> xSet (xController, UNO_QUERY);
441         if (xSet.is())
442         {
443                 try
444                 {
445                     xSet->addPropertyChangeListener(msCurrentPagePropertyName, this);
446                 }
447                 catch (beans::UnknownPropertyException)
448                 {
449                     OSL_TRACE("EventMultiplexer::ConnectToController: CurrentPage unknown");
450                 }
451 
452                 try
453                 {
454                     xSet->addPropertyChangeListener(msEditModePropertyName, this);
455                 }
456                 catch (beans::UnknownPropertyException)
457                 {
458                     OSL_TRACE("EventMultiplexer::ConnectToController: IsMasterPageMode unknown");
459                 }
460         }
461 
462         // Listen for selection change events.
463         Reference<view::XSelectionSupplier> xSelection (xController, UNO_QUERY);
464         if (xSelection.is())
465         {
466             xSelection->addSelectionChangeListener(this);
467         }
468     }
469     catch (const lang::DisposedException aException)
470     {
471         mbListeningToController = false;
472     }
473 }
474 
475 
476 
477 
478 void EventMultiplexer::Implementation::DisconnectFromController (void)
479 {
480     if (mbListeningToController)
481     {
482         mbListeningToController = false;
483 
484         Reference<frame::XController> xController = mxControllerWeak;
485 
486         Reference<beans::XPropertySet> xSet (xController, UNO_QUERY);
487         // Remove the property listener.
488         if (xSet.is())
489         {
490             try
491             {
492                 xSet->removePropertyChangeListener(msCurrentPagePropertyName, this);
493             }
494             catch (beans::UnknownPropertyException aEvent)
495             {
496                 OSL_TRACE ("DisconnectFromController: CurrentPage unknown");
497             }
498 
499             try
500             {
501                 xSet->removePropertyChangeListener(msEditModePropertyName, this);
502             }
503             catch (beans::UnknownPropertyException aEvent)
504             {
505                 OSL_TRACE ("DisconnectFromController: IsMasterPageMode unknown");
506             }
507         }
508 
509         // Remove selection change listener.
510         Reference<view::XSelectionSupplier> xSelection (xController, UNO_QUERY);
511         if (xSelection.is())
512         {
513             xSelection->removeSelectionChangeListener(this);
514         }
515 
516         // Remove listener for disposing events.
517         Reference<lang::XComponent> xComponent (xController, UNO_QUERY);
518         if (xComponent.is())
519         {
520             xComponent->removeEventListener (
521                 Reference<lang::XEventListener>(static_cast<XWeak*>(this), UNO_QUERY));
522         }
523     }
524 }
525 
526 
527 
528 
529 //=====  lang::XEventListener  ================================================
530 
531 void SAL_CALL EventMultiplexer::Implementation::disposing (
532     const lang::EventObject& rEventObject)
533     throw (RuntimeException)
534 {
535     if (mbListeningToController)
536     {
537         Reference<frame::XController> xController (mxControllerWeak);
538         if (rEventObject.Source == xController)
539         {
540             mbListeningToController = false;
541         }
542     }
543 
544     Reference<XConfigurationController> xConfigurationController (
545         mxConfigurationControllerWeak);
546     if (xConfigurationController.is()
547         && rEventObject.Source == xConfigurationController)
548     {
549         mxConfigurationControllerWeak = Reference<XConfigurationController>();
550     }
551 }
552 
553 
554 
555 
556 //=====  beans::XPropertySetListener  =========================================
557 
558 void SAL_CALL EventMultiplexer::Implementation::propertyChange (
559     const beans::PropertyChangeEvent& rEvent)
560     throw (RuntimeException)
561 {
562     ThrowIfDisposed();
563 
564     if (rEvent.PropertyName.equals(msCurrentPagePropertyName))
565     {
566         CallListeners(EventMultiplexerEvent::EID_CURRENT_PAGE);
567     }
568     else if (rEvent.PropertyName.equals(msEditModePropertyName))
569     {
570         bool bIsMasterPageMode (false);
571         rEvent.NewValue >>= bIsMasterPageMode;
572         if (bIsMasterPageMode)
573             CallListeners(EventMultiplexerEvent::EID_EDIT_MODE_MASTER);
574         else
575             CallListeners(EventMultiplexerEvent::EID_EDIT_MODE_NORMAL);
576     }
577 }
578 
579 
580 
581 
582 //===== frame::XFrameActionListener  ==========================================
583 
584 void SAL_CALL EventMultiplexer::Implementation::frameAction (
585     const frame::FrameActionEvent& rEvent)
586     throw (::com::sun::star::uno::RuntimeException)
587 {
588     Reference<frame::XFrame> xFrame (mxFrameWeak);
589     if (rEvent.Frame == xFrame)
590         switch (rEvent.Action)
591         {
592             case frame::FrameAction_COMPONENT_DETACHING:
593                 DisconnectFromController();
594                 CallListeners (EventMultiplexerEvent::EID_CONTROLLER_DETACHED);
595                 break;
596 
597             case frame::FrameAction_COMPONENT_REATTACHED:
598                 CallListeners (EventMultiplexerEvent::EID_CONTROLLER_DETACHED);
599                 DisconnectFromController();
600                 ConnectToController();
601                 CallListeners (EventMultiplexerEvent::EID_CONTROLLER_ATTACHED);
602                 break;
603 
604             case frame::FrameAction_COMPONENT_ATTACHED:
605                 ConnectToController();
606                 CallListeners (EventMultiplexerEvent::EID_CONTROLLER_ATTACHED);
607                 break;
608 
609             default:
610                 break;
611         }
612 }
613 
614 
615 
616 
617 //===== view::XSelectionChangeListener ========================================
618 
619 void SAL_CALL EventMultiplexer::Implementation::selectionChanged (
620     const lang::EventObject& )
621     throw (::com::sun::star::uno::RuntimeException)
622 {
623     CallListeners (EventMultiplexerEvent::EID_EDIT_VIEW_SELECTION);
624 }
625 
626 
627 
628 
629 //===== drawing::framework::XConfigurationChangeListener ==================
630 
631 void SAL_CALL EventMultiplexer::Implementation::notifyConfigurationChange (
632     const ConfigurationChangeEvent& rEvent)
633     throw (RuntimeException)
634 {
635     sal_Int32 nEventType = 0;
636     rEvent.UserData >>= nEventType;
637     switch (nEventType)
638     {
639         case ResourceActivationEvent:
640             if (rEvent.ResourceId->getResourceURL().match(FrameworkHelper::msViewURLPrefix))
641             {
642                 CallListeners (EventMultiplexerEvent::EID_VIEW_ADDED);
643 
644                 if (rEvent.ResourceId->isBoundToURL(
645                     FrameworkHelper::msCenterPaneURL, AnchorBindingMode_DIRECT))
646                 {
647                     CallListeners (EventMultiplexerEvent::EID_MAIN_VIEW_ADDED);
648                 }
649 
650                 // Add selection change listener at slide sorter.
651                 if (rEvent.ResourceId->getResourceURL().equals(FrameworkHelper::msSlideSorterURL))
652                 {
653                     slidesorter::SlideSorterViewShell* pViewShell
654                         = dynamic_cast<slidesorter::SlideSorterViewShell*>(
655                             FrameworkHelper::GetViewShell(
656                                 Reference<XView>(rEvent.ResourceObject,UNO_QUERY)).get());
657                     if (pViewShell != NULL)
658                         pViewShell->AddSelectionChangeListener (
659                             LINK(this,
660                                 EventMultiplexer::Implementation,
661                                 SlideSorterSelectionChangeListener));
662                 }
663             }
664             break;
665 
666         case ResourceDeactivationEvent:
667             if (rEvent.ResourceId->getResourceURL().match(FrameworkHelper::msViewURLPrefix))
668             {
669                 CallListeners (EventMultiplexerEvent::EID_VIEW_REMOVED);
670 
671                 if (rEvent.ResourceId->isBoundToURL(
672                     FrameworkHelper::msCenterPaneURL, AnchorBindingMode_DIRECT))
673                 {
674                     CallListeners (EventMultiplexerEvent::EID_MAIN_VIEW_REMOVED);
675                 }
676 
677                 // Remove selection change listener from slide sorter.  Add
678                 // selection change listener at slide sorter.
679                 if (rEvent.ResourceId->getResourceURL().equals(FrameworkHelper::msSlideSorterURL))
680                 {
681                     slidesorter::SlideSorterViewShell* pViewShell
682                         = dynamic_cast<slidesorter::SlideSorterViewShell*>(
683                             FrameworkHelper::GetViewShell(
684                                 Reference<XView>(rEvent.ResourceObject, UNO_QUERY)).get());
685                     if (pViewShell != NULL)
686                         pViewShell->RemoveSelectionChangeListener (
687                             LINK(this,
688                                 EventMultiplexer::Implementation,
689                                 SlideSorterSelectionChangeListener));
690                 }
691             }
692             break;
693 
694         case ConfigurationUpdateEvent:
695             CallListeners (EventMultiplexerEvent::EID_CONFIGURATION_UPDATED);
696             break;
697     }
698 
699 }
700 
701 
702 
703 
704 void SAL_CALL EventMultiplexer::Implementation::disposing (void)
705 {
706     CallListeners (EventMultiplexerEvent::EID_DISPOSING);
707     ReleaseListeners();
708 }
709 
710 
711 
712 
713 void EventMultiplexer::Implementation::ThrowIfDisposed (void)
714     throw (::com::sun::star::lang::DisposedException)
715 {
716 	if (rBHelper.bDisposed || rBHelper.bInDispose)
717 	{
718         throw lang::DisposedException (
719             ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
720                 "SlideSorterController object has already been disposed")),
721             static_cast<uno::XWeak*>(this));
722     }
723 }
724 
725 
726 
727 
728 void EventMultiplexer::Implementation::Notify (
729     SfxBroadcaster&,
730     const SfxHint& rHint)
731 {
732     if (rHint.ISA(SdrHint))
733     {
734         SdrHint& rSdrHint (*PTR_CAST(SdrHint,&rHint));
735         switch (rSdrHint.GetKind())
736         {
737             case HINT_MODELCLEARED:
738             case HINT_PAGEORDERCHG:
739                 CallListeners (EventMultiplexerEvent::EID_PAGE_ORDER);
740                 break;
741 
742             case HINT_SWITCHTOPAGE:
743                 CallListeners (EventMultiplexerEvent::EID_CURRENT_PAGE);
744                 break;
745 
746             case HINT_OBJCHG:
747                 CallListeners(EventMultiplexerEvent::EID_SHAPE_CHANGED,
748                     const_cast<void*>(static_cast<const void*>(rSdrHint.GetPage())));
749                 break;
750 
751             case HINT_OBJINSERTED:
752                 CallListeners(EventMultiplexerEvent::EID_SHAPE_INSERTED,
753                     const_cast<void*>(static_cast<const void*>(rSdrHint.GetPage())));
754                 break;
755 
756             case HINT_OBJREMOVED:
757                 CallListeners(EventMultiplexerEvent::EID_SHAPE_REMOVED,
758                     const_cast<void*>(static_cast<const void*>(rSdrHint.GetPage())));
759                 break;
760 			default:
761 				break;
762         }
763     }
764     else if (rHint.ISA(SfxSimpleHint))
765     {
766         SfxSimpleHint& rSimpleHint (*PTR_CAST(SfxSimpleHint, &rHint));
767         if (rSimpleHint.GetId() == SFX_HINT_DYING)
768             mpDocument = NULL;
769     }
770 }
771 
772 
773 
774 
775 void EventMultiplexer::Implementation::CallListeners (
776     EventMultiplexerEvent::EventId eId,
777     void* pUserData)
778 {
779     EventMultiplexerEvent aEvent (mrBase, eId, pUserData);
780     CallListeners(aEvent);
781 }
782 
783 
784 
785 
786 void EventMultiplexer::Implementation::CallListeners (EventMultiplexerEvent& rEvent)
787 {
788     ListenerList aCopyListeners( maListeners );
789     ListenerList::iterator iListener (aCopyListeners.begin());
790     ListenerList::const_iterator iListenerEnd (aCopyListeners.end());
791     for (; iListener!=iListenerEnd; ++iListener)
792     {
793         if ((iListener->second && rEvent.meEventId) != 0)
794             iListener->first.Call(&rEvent);
795     }
796 }
797 
798 
799 
800 
801 IMPL_LINK(EventMultiplexer::Implementation, SlideSorterSelectionChangeListener, void*, EMPTYARG)
802 {
803     CallListeners (EventMultiplexerEvent::EID_SLIDE_SORTER_SELECTION);
804     return 0;
805 }
806 
807 
808 
809 
810 //===== EventMultiplexerEvent =================================================
811 
812 EventMultiplexerEvent::EventMultiplexerEvent (
813     const ViewShellBase& rBase,
814     EventId eEventId,
815     const void* pUserData)
816     : mrBase(rBase),
817       meEventId(eEventId),
818       mpUserData(pUserData)
819 
820 {
821 }
822 
823 } } // end of namespace ::sd::tools
824