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