bump product version to 4.1.6.2
[LibreOffice.git] / reportdesign / source / ui / report / ReportControllerObserver.cxx
blobcc9890eecb9cf1c17771fe3c8b4ce1534ef6a30f
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
21 #include <ReportControllerObserver.hxx>
22 #include <ReportController.hxx>
23 #include <svl/smplhint.hxx>
24 #include <osl/mutex.hxx>
25 #include <vcl/svapp.hxx>
26 #include <com/sun/star/report/XFormattedField.hpp>
27 #include <com/sun/star/awt/FontSlant.hpp>
28 #include <FormattedFieldBeautifier.hxx>
30 #include <svx/unopage.hxx>
32 // DBG_*
33 #include <tools/debug.hxx>
34 // DBG_UNHANDLED_EXCEPTION
35 #include <tools/diagnose_ex.h>
37 namespace rptui
40 using namespace ::com::sun::star;
42 DECLARE_STL_USTRINGACCESS_MAP(bool, AllProperties);
43 DECLARE_STL_STDKEY_MAP(uno::Reference< beans::XPropertySet >, AllProperties, PropertySetInfoCache);
45 class OXReportControllerObserverImpl
47 OXReportControllerObserverImpl(OXReportControllerObserverImpl&);
48 void operator =(OXReportControllerObserverImpl&);
49 public:
50 const OReportController& m_rReportController;
51 ::std::vector< uno::Reference< container::XChild> > m_aSections;
52 ::osl::Mutex m_aMutex;
53 oslInterlockedCount m_nLocks;
54 sal_Bool m_bReadOnly;
56 OXReportControllerObserverImpl(const OReportController& _rController);
57 ~OXReportControllerObserverImpl();
60 // -----------------------------------------------------------------------------
62 OXReportControllerObserverImpl::OXReportControllerObserverImpl(const OReportController& _rController)
63 :m_rReportController(_rController)
64 ,m_nLocks(0)
65 ,m_bReadOnly(sal_False)
69 OXReportControllerObserverImpl::~OXReportControllerObserverImpl()
73 // -----------------------------------------------------------------------------
74 // -----------------------------------------------------------------------------
75 // -----------------------------------------------------------------------------
77 DBG_NAME(rpt_OXReportControllerObserver)
79 OXReportControllerObserver::OXReportControllerObserver(const OReportController& _rController)
80 :m_pImpl(new OXReportControllerObserverImpl(_rController) )
81 ,m_aFormattedFieldBeautifier(_rController)
82 ,m_aFixedTextColor(_rController)
84 DBG_CTOR( rpt_OXReportControllerObserver,NULL);
86 Application::AddEventListener(LINK( this, OXReportControllerObserver, SettingsChanged ) );
89 OXReportControllerObserver::~OXReportControllerObserver()
91 DBG_CTOR( rpt_OXReportControllerObserver,NULL);
92 Application::RemoveEventListener(LINK( this, OXReportControllerObserver, SettingsChanged ) );
95 // -----------------------------------------------------------------------------
96 IMPL_LINK(OXReportControllerObserver, SettingsChanged, VclWindowEvent*, _pEvt)
98 if ( _pEvt )
100 sal_Int32 nEvent = _pEvt->GetId();
102 if (nEvent == VCLEVENT_APPLICATION_DATACHANGED )
104 DataChangedEvent* pData = reinterpret_cast<DataChangedEvent*>(_pEvt->GetData());
105 if ( pData && ((( pData->GetType() == DATACHANGED_SETTINGS ) ||
106 ( pData->GetType() == DATACHANGED_DISPLAY )) &&
107 ( pData->GetFlags() & SETTINGS_STYLE )))
109 OEnvLock aLock(*this);
111 // send all Section Objects a 'tingle'
112 // maybe they need a change in format, color, etc
113 ::std::vector< uno::Reference< container::XChild > >::const_iterator aIter = m_pImpl->m_aSections.begin();
114 ::std::vector< uno::Reference< container::XChild > >::const_iterator aEnd = m_pImpl->m_aSections.end();
115 for (;aIter != aEnd; ++aIter)
117 const uno::Reference<container::XChild> xChild (*aIter);
118 if (xChild.is())
120 uno::Reference<report::XSection> xSection(xChild, uno::UNO_QUERY);
121 if (xSection.is())
123 const sal_Int32 nCount = xSection->getCount();
124 for (sal_Int32 i = 0; i < nCount; ++i)
126 const uno::Any aObj = xSection->getByIndex(i);
127 uno::Reference < report::XReportComponent > xReportComponent(aObj, uno::UNO_QUERY);
128 if (xReportComponent.is())
130 m_aFormattedFieldBeautifier.handle(xReportComponent);
131 m_aFixedTextColor.handle(xReportComponent);
141 return 0L;
144 // XEventListener
145 void SAL_CALL OXReportControllerObserver::disposing(const lang::EventObject& e) throw( uno::RuntimeException )
147 (void) e;
148 // check if it's an object we have cached information about
149 uno::Reference< beans::XPropertySet > xSourceSet(e.Source, uno::UNO_QUERY);
150 if ( xSourceSet.is() )
152 uno::Reference< report::XSection> xSection(xSourceSet,uno::UNO_QUERY);
153 if ( xSection.is() )
154 RemoveSection(xSection);
155 else
156 RemoveElement(xSourceSet);
160 void OXReportControllerObserver::Clear()
162 OEnvLock aLock(*this);
163 m_pImpl->m_aSections.clear();
166 // XPropertyChangeListener
167 void SAL_CALL OXReportControllerObserver::propertyChange(const beans::PropertyChangeEvent& _rEvent) throw(uno::RuntimeException)
169 (void) _rEvent;
170 ::osl::ClearableMutexGuard aGuard( m_pImpl->m_aMutex );
172 if ( IsLocked() )
173 return;
175 m_aFormattedFieldBeautifier.notifyPropertyChange(_rEvent);
176 m_aFixedTextColor.notifyPropertyChange(_rEvent);
179 // -----------------------------------------------------------------------------
180 void OXReportControllerObserver::Lock()
182 OSL_ENSURE(m_refCount,"Illegal call to dead object!");
183 osl_atomic_increment( &m_pImpl->m_nLocks );
185 void OXReportControllerObserver::UnLock()
187 OSL_ENSURE(m_refCount,"Illegal call to dead object!");
189 osl_atomic_decrement( &m_pImpl->m_nLocks );
191 sal_Bool OXReportControllerObserver::IsLocked() const { return m_pImpl->m_nLocks != 0; }
193 //------------------------------------------------------------------------------
194 void OXReportControllerObserver::AddSection(const uno::Reference< report::XSection > & _xSection)
196 OEnvLock aLock(*this);
199 uno::Reference<container::XChild> xChild = _xSection.get();
200 m_pImpl->m_aSections.push_back(xChild);
201 uno::Reference< uno::XInterface > xInt(_xSection);
202 AddElement(xInt);
204 catch(const uno::Exception&)
206 DBG_UNHANDLED_EXCEPTION();
210 //------------------------------------------------------------------------------
211 void OXReportControllerObserver::RemoveSection(const uno::Reference< report::XSection > & _xSection)
213 OEnvLock aLock(*this);
216 uno::Reference<container::XChild> xChild(_xSection.get());
217 m_pImpl->m_aSections.erase(::std::remove(m_pImpl->m_aSections.begin(),m_pImpl->m_aSections.end(),
218 xChild), m_pImpl->m_aSections.end());
219 uno::Reference< uno::XInterface > xInt(_xSection);
220 RemoveElement(xInt);
222 catch(uno::Exception&)
224 DBG_UNHANDLED_EXCEPTION();
228 //------------------------------------------------------------------------------
229 void OXReportControllerObserver::TogglePropertyListening(const uno::Reference< uno::XInterface > & Element)
231 // listen at Container
232 uno::Reference< container::XIndexAccess > xContainer(Element, uno::UNO_QUERY);
233 if (xContainer.is())
235 uno::Reference< uno::XInterface > xInterface;
236 sal_Int32 nCount = xContainer->getCount();
237 for(sal_Int32 i = 0;i != nCount;++i)
239 xInterface.set(xContainer->getByIndex( i ),uno::UNO_QUERY);
240 TogglePropertyListening(xInterface);
244 uno::Reference< beans::XPropertySet > xSet(Element, uno::UNO_QUERY);
245 if (xSet.is())
247 if (!m_pImpl->m_bReadOnly)
248 xSet->addPropertyChangeListener( OUString(), this );
249 else
250 xSet->removePropertyChangeListener( OUString(), this );
255 //------------------------------------------------------------------------------
256 void OXReportControllerObserver::switchListening( const uno::Reference< container::XIndexAccess >& _rxContainer, bool _bStartListening ) SAL_THROW(())
258 OSL_PRECOND( _rxContainer.is(), "OXReportControllerObserver::switchListening: invalid container!" );
259 if ( !_rxContainer.is() )
260 return;
264 // also handle all children of this element
265 uno::Reference< uno::XInterface > xInterface;
266 sal_Int32 nCount = _rxContainer->getCount();
267 for(sal_Int32 i = 0;i != nCount;++i)
269 xInterface.set(_rxContainer->getByIndex( i ),uno::UNO_QUERY);
270 if ( _bStartListening )
271 AddElement( xInterface );
272 else
273 RemoveElement( xInterface );
276 // be notified of any changes in the container elements
277 uno::Reference< container::XContainer > xSimpleContainer( _rxContainer, uno::UNO_QUERY );
278 if ( xSimpleContainer.is() )
280 if ( _bStartListening )
281 xSimpleContainer->addContainerListener( this );
282 else
283 xSimpleContainer->removeContainerListener( this );
286 catch( const uno::Exception& )
288 DBG_UNHANDLED_EXCEPTION();
292 //------------------------------------------------------------------------------
293 void OXReportControllerObserver::switchListening( const uno::Reference< uno::XInterface >& _rxObject, bool _bStartListening ) SAL_THROW(())
295 OSL_PRECOND( _rxObject.is(), "OXReportControllerObserver::switchListening: how should I listen at a NULL object?" );
299 if ( !m_pImpl->m_bReadOnly )
301 uno::Reference< beans::XPropertySet > xProps( _rxObject, uno::UNO_QUERY );
302 if ( xProps.is() )
304 if ( _bStartListening )
305 xProps->addPropertyChangeListener( OUString(), this );
306 else
307 xProps->removePropertyChangeListener( OUString(), this );
311 uno::Reference< util::XModifyBroadcaster > xBroadcaster( _rxObject, uno::UNO_QUERY );
312 if ( xBroadcaster.is() )
314 if ( _bStartListening )
315 xBroadcaster->addModifyListener( this );
316 else
317 xBroadcaster->removeModifyListener( this );
320 catch( const uno::Exception& )
322 DBG_UNHANDLED_EXCEPTION();
326 //------------------------------------------------------------------------------
327 void SAL_CALL OXReportControllerObserver::modified( const lang::EventObject& /*aEvent*/ ) throw (uno::RuntimeException)
331 //------------------------------------------------------------------------------
332 void OXReportControllerObserver::AddElement(const uno::Reference< uno::XInterface >& _rxElement )
334 m_aFormattedFieldBeautifier.notifyElementInserted(_rxElement);
335 m_aFixedTextColor.notifyElementInserted(_rxElement);
337 // if it's a container, start listening at all elements
338 uno::Reference< container::XIndexAccess > xContainer( _rxElement, uno::UNO_QUERY );
339 if ( xContainer.is() )
340 switchListening( xContainer, true );
342 switchListening( _rxElement, true );
345 //------------------------------------------------------------------------------
346 void OXReportControllerObserver::RemoveElement(const uno::Reference< uno::XInterface >& _rxElement)
348 switchListening( _rxElement, false );
350 uno::Reference< container::XIndexAccess > xContainer( _rxElement, uno::UNO_QUERY );
351 if ( xContainer.is() )
352 switchListening( xContainer, false );
355 // -----------------------------------------------------------------------------
356 ::std::vector< uno::Reference< container::XChild> >::const_iterator OXReportControllerObserver::getSection(const uno::Reference<container::XChild>& _xContainer) const
358 ::std::vector< uno::Reference< container::XChild> >::const_iterator aFind = m_pImpl->m_aSections.end();
359 if ( _xContainer.is() )
361 aFind = ::std::find(m_pImpl->m_aSections.begin(),m_pImpl->m_aSections.end(),_xContainer);
363 if ( aFind == m_pImpl->m_aSections.end() )
365 uno::Reference<container::XChild> xParent(_xContainer->getParent(),uno::UNO_QUERY);
366 aFind = getSection(xParent);
369 return aFind;
371 // XContainerListener
372 //------------------------------------------------------------------------------
373 void SAL_CALL OXReportControllerObserver::elementInserted(const container::ContainerEvent& evt) throw(uno::RuntimeException)
375 SolarMutexGuard aSolarGuard;
376 ::osl::MutexGuard aGuard( m_pImpl->m_aMutex );
378 // neues Object zum lauschen
379 uno::Reference< uno::XInterface > xIface( evt.Element, uno::UNO_QUERY );
380 if ( xIface.is() )
382 AddElement(xIface);
386 //------------------------------------------------------------------------------
387 void SAL_CALL OXReportControllerObserver::elementReplaced(const container::ContainerEvent& evt) throw(uno::RuntimeException)
389 SolarMutexGuard aSolarGuard;
390 ::osl::MutexGuard aGuard( m_pImpl->m_aMutex );
392 uno::Reference< uno::XInterface > xIface(evt.ReplacedElement,uno::UNO_QUERY);
393 OSL_ENSURE(xIface.is(), "OXReportControllerObserver::elementReplaced: invalid container notification!");
394 RemoveElement(xIface);
396 xIface.set(evt.Element,uno::UNO_QUERY);
397 AddElement(xIface);
400 //------------------------------------------------------------------------------
401 void SAL_CALL OXReportControllerObserver::elementRemoved(const container::ContainerEvent& evt) throw(uno::RuntimeException)
403 SolarMutexGuard aSolarGuard;
404 ::osl::MutexGuard aGuard( m_pImpl->m_aMutex );
406 uno::Reference< uno::XInterface > xIface( evt.Element, uno::UNO_QUERY );
407 if ( xIface.is() )
409 RemoveElement(xIface);
414 } // namespace rptui
418 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */