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