LibreOffice Module svx (master)  1
formfeaturedispatcher.cxx
Go to the documentation of this file.
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3  * This file is part of the LibreOffice project.
4  *
5  * This Source Code Form is subject to the terms of the Mozilla Public
6  * License, v. 2.0. If a copy of the MPL was not distributed with this
7  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8  *
9  * This file incorporates work covered by the following license notice:
10  *
11  * Licensed to the Apache Software Foundation (ASF) under one or more
12  * contributor license agreements. See the NOTICE file distributed
13  * with this work for additional information regarding copyright
14  * ownership. The ASF licenses this file to you under the Apache
15  * License, Version 2.0 (the "License"); you may not use this file
16  * except in compliance with the License. You may obtain a copy of
17  * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18  */
19 
20 
22 
24 #include <tools/diagnose_ex.h>
25 
26 
27 namespace svx
28 {
29 
30 
31  using namespace ::com::sun::star::uno;
32  using namespace ::com::sun::star::lang;
33  using namespace ::com::sun::star::frame;
34  using namespace ::com::sun::star::beans;
35  using namespace ::com::sun::star::util;
36  using namespace ::com::sun::star::form::runtime;
37 
38  OSingleFeatureDispatcher::OSingleFeatureDispatcher( const URL& _rFeatureURL, const sal_Int16 _nFormFeature,
39  const Reference< XFormOperations >& _rxFormOperations, ::osl::Mutex& _rMutex )
40  :m_rMutex( _rMutex )
41  ,m_aStatusListeners( _rMutex )
42  ,m_xFormOperations( _rxFormOperations )
43  ,m_aFeatureURL( _rFeatureURL )
44  ,m_nFormFeature( _nFormFeature )
45  ,m_bLastKnownEnabled( false )
46  {
47  }
48 
49 
50  void OSingleFeatureDispatcher::getUnoState( FeatureStateEvent& /* [out] */ _rState ) const
51  {
52  _rState.Source = *const_cast< OSingleFeatureDispatcher* >( this );
53 
54  FeatureState aState( m_xFormOperations->getState( m_nFormFeature ) );
55 
56  _rState.FeatureURL = m_aFeatureURL;
57  _rState.IsEnabled = aState.Enabled;
58  _rState.Requery = false;
59  _rState.State = aState.State;
60  }
61 
62 
64  {
65  ::osl::ClearableMutexGuard aGuard( m_rMutex );
66 
67  FeatureStateEvent aUnoState;
68  getUnoState( aUnoState );
69 
70  if ( ( m_aLastKnownState == aUnoState.State ) && ( m_bLastKnownEnabled == bool(aUnoState.IsEnabled) ) )
71  return;
72 
73  m_aLastKnownState = aUnoState.State;
74  m_bLastKnownEnabled = aUnoState.IsEnabled;
75 
76  notifyStatus( nullptr, aGuard );
77  }
78 
79 
80  void OSingleFeatureDispatcher::notifyStatus( const Reference< XStatusListener >& _rxListener, ::osl::ClearableMutexGuard& _rFreeForNotification )
81  {
82  FeatureStateEvent aUnoState;
83  getUnoState( aUnoState );
84 
85  if ( _rxListener.is() )
86  {
87  try
88  {
89  _rFreeForNotification.clear();
90  _rxListener->statusChanged( aUnoState );
91  }
92  catch( const Exception& )
93  {
94  TOOLS_WARN_EXCEPTION( "svx", "OSingleFeatureDispatcher::notifyStatus" );
95  }
96  }
97  else
98  {
100  _rFreeForNotification.clear();
101 
102  while ( aIter.hasMoreElements() )
103  {
104  try
105  {
106  static_cast< XStatusListener* >( aIter.next() )->statusChanged( aUnoState );
107  }
108  catch( const DisposedException& )
109  {
110  TOOLS_WARN_EXCEPTION("svx.form",
111  "caught a DisposedException - removing the listener!");
112  aIter.remove( );
113  }
114  catch( const Exception& )
115  {
117  "svx.form",
118  "caught a generic exception while notifying a single listener!");
119  }
120  }
121  }
122  }
123 
124 
125  void SAL_CALL OSingleFeatureDispatcher::dispatch( const URL& _rURL, const Sequence< PropertyValue >& _rArguments )
126  {
127  ::osl::ClearableMutexGuard aGuard( m_rMutex );
128 
129  OSL_ENSURE( _rURL.Complete == m_aFeatureURL.Complete, "OSingleFeatureDispatcher::dispatch: not responsible for this URL!" );
130 
131  if ( !m_xFormOperations->isEnabled( m_nFormFeature ) )
132  return;
133 
134  // release our mutex before executing the command
135  sal_Int16 nFormFeature( m_nFormFeature );
136  Reference< XFormOperations > xFormOperations( m_xFormOperations );
137  aGuard.clear();
138 
139  try
140  {
141  if ( !_rArguments.hasElements() )
142  {
143  xFormOperations->execute( nFormFeature );
144  }
145  else
146  { // at the moment we only support one parameter
147  ::comphelper::NamedValueCollection aArgs( _rArguments );
148  xFormOperations->executeWithArguments( nFormFeature, aArgs.getNamedValues() );
149  }
150  }
151  catch( const RuntimeException& )
152  {
153  throw;
154  }
155  catch( const Exception& )
156  {
158  }
159  }
160 
161 
162  void SAL_CALL OSingleFeatureDispatcher::addStatusListener( const Reference< XStatusListener >& _rxControl, const URL& _rURL )
163  {
164  OSL_ENSURE( _rURL.Complete == m_aFeatureURL.Complete, "OSingleFeatureDispatcher::addStatusListener: unexpected URL!" );
165  OSL_ENSURE( _rxControl.is(), "OSingleFeatureDispatcher::addStatusListener: senseless call!" );
166  if ( !_rxControl.is() )
167  return;
168 
169  ::osl::ClearableMutexGuard aGuard( m_rMutex );
170 
171  m_aStatusListeners.addInterface( _rxControl );
172 
173  // initially update the status
174  notifyStatus( _rxControl, aGuard );
175  }
176 
177 
178  void SAL_CALL OSingleFeatureDispatcher::removeStatusListener( const Reference< XStatusListener >& _rxControl, const URL& _rURL )
179  {
180  OSL_ENSURE( _rURL.Complete == m_aFeatureURL.Complete, "OSingleFeatureDispatcher::removeStatusListener: unexpected URL!" );
181  OSL_ENSURE( _rxControl.is(), "OSingleFeatureDispatcher::removeStatusListener: senseless call!" );
182  if ( !_rxControl.is() )
183  return;
184 
185  ::osl::MutexGuard aGuard( m_rMutex );
186 
187  m_aStatusListeners.removeInterface( _rxControl );
188  }
189 
190 
191 }
192 
193 
194 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
css::uno::Sequence< css::beans::NamedValue > getNamedValues() const
virtual void SAL_CALL addStatusListener(const css::uno::Reference< css::frame::XStatusListener > &_rxControl, const css::util::URL &_rURL) override
::osl::Mutex & m_rMutex
sal_Int32 addInterface(const css::uno::Reference< css::uno::XInterface > &rxIFace)
sal_Int32 removeInterface(const css::uno::Reference< css::uno::XInterface > &rxIFace)
virtual void SAL_CALL removeStatusListener(const css::uno::Reference< css::frame::XStatusListener > &_rxControl, const css::util::URL &_rURL) override
virtual void SAL_CALL dispatch(const css::util::URL &_rURL, const css::uno::Sequence< css::beans::PropertyValue > &_rArguments) override
#define DBG_UNHANDLED_EXCEPTION(...)
#define TOOLS_WARN_EXCEPTION(area, stream)
void notifyStatus(const css::uno::Reference< css::frame::XStatusListener > &_rxListener,::osl::ClearableMutexGuard &_rFreeForNotification)
notifies our current state to one or all listeners
const sal_Int16 nFormFeature
::comphelper::OInterfaceContainerHelper2 m_aStatusListeners
css::uno::Reference< css::form::runtime::XFormOperations > m_xFormOperations
void getUnoState(css::frame::FeatureStateEvent &_rState) const
retrieves the current status of our feature, in a format which can be used for UNO notifications ...
css::uno::XInterface * next()
void updateAllListeners()
notifies all our listeners of the current state
OSingleFeatureDispatcher(const css::util::URL &_rFeatureURL, const sal_Int16 _nFormFeature, const css::uno::Reference< css::form::runtime::XFormOperations > &_rxFormOperations,::osl::Mutex &_rMutex)
constructs the dispatcher