update dev300-m58
[ooovba.git] / reportdesign / source / ui / report / ReportControllerObserver.cxx
blob56b1d715217743273ac5f96d07474105aee2c459
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: UndoEnv.hxx,v $
10 * $Revision: 1.4 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_reportdesign.hxx"
34 #include <ReportControllerObserver.hxx>
35 #include <ReportController.hxx>
36 #include <svtools/smplhint.hxx>
37 #include <vos/mutex.hxx>
38 #include <vcl/svapp.hxx>
39 #include <com/sun/star/report/XFormattedField.hpp>
40 #include <com/sun/star/awt/FontSlant.hpp>
41 #include <FormattedFieldBeautifier.hxx>
43 #include <svx/unopage.hxx>
45 // DBG_*
46 #include <tools/debug.hxx>
47 // DBG_UNHANDLED_EXCEPTION
48 #include <tools/diagnose_ex.h>
50 namespace rptui
53 using namespace ::com::sun::star;
55 // const OReportController *& m_pReportController;
57 DECLARE_STL_USTRINGACCESS_MAP(bool, AllProperties);
58 DECLARE_STL_STDKEY_MAP(uno::Reference< beans::XPropertySet >, AllProperties, PropertySetInfoCache);
60 class OXReportControllerObserverImpl
62 OXReportControllerObserverImpl(OXReportControllerObserverImpl&);
63 void operator =(OXReportControllerObserverImpl&);
64 public:
65 const OReportController& m_rReportController;
66 ::std::vector< uno::Reference< container::XChild> > m_aSections;
67 ::osl::Mutex m_aMutex;
68 oslInterlockedCount m_nLocks;
69 sal_Bool m_bReadOnly;
71 OXReportControllerObserverImpl(const OReportController& _rController);
72 ~OXReportControllerObserverImpl();
75 // -----------------------------------------------------------------------------
77 OXReportControllerObserverImpl::OXReportControllerObserverImpl(const OReportController& _rController)
78 :m_rReportController(_rController)
79 ,m_nLocks(0)
80 ,m_bReadOnly(sal_False)
84 OXReportControllerObserverImpl::~OXReportControllerObserverImpl()
88 // -----------------------------------------------------------------------------
89 // -----------------------------------------------------------------------------
90 // -----------------------------------------------------------------------------
92 DBG_NAME(rpt_OXReportControllerObserver)
94 OXReportControllerObserver::OXReportControllerObserver(const OReportController& _rController)
95 :m_pImpl(new OXReportControllerObserverImpl(_rController) )
96 ,m_aFormattedFieldBeautifier(_rController)
97 ,m_aFixedTextColor(_rController)
99 DBG_CTOR( rpt_OXReportControllerObserver,NULL);
101 Application::AddEventListener(LINK( this, OXReportControllerObserver, SettingsChanged ) );
104 OXReportControllerObserver::~OXReportControllerObserver()
106 DBG_CTOR( rpt_OXReportControllerObserver,NULL);
107 Application::RemoveEventListener(LINK( this, OXReportControllerObserver, SettingsChanged ) );
110 // -----------------------------------------------------------------------------
111 IMPL_LINK(OXReportControllerObserver, SettingsChanged, VclWindowEvent*, _pEvt)
113 if ( _pEvt )
115 sal_Int32 nEvent = _pEvt->GetId();
117 // just for debug
118 if (nEvent == VCLEVENT_WINDOW_CHILDCREATED ||
119 nEvent == VCLEVENT_WINDOW_PAINT ||
120 nEvent == VCLEVENT_WINDOW_MOVE ||
121 nEvent == VCLEVENT_WINDOW_RESIZE ||
122 nEvent == VCLEVENT_WINDOW_SHOW ||
123 nEvent == VCLEVENT_WINDOW_MOUSEMOVE ||
124 nEvent == VCLEVENT_WINDOW_FRAMETITLECHANGED ||
125 nEvent == VCLEVENT_WINDOW_HIDE ||
126 nEvent == VCLEVENT_EDIT_MODIFY ||
127 nEvent == VCLEVENT_SCROLLBAR_ENDSCROLL ||
128 nEvent == VCLEVENT_EDIT_SELECTIONCHANGED ||
129 nEvent == VCLEVENT_TABPAGE_INSERTED ||
130 nEvent == VCLEVENT_TABPAGE_REMOVED ||
131 nEvent == VCLEVENT_TOOLBOX_FORMATCHANGED ||
132 nEvent == VCLEVENT_TOOLBOX_ITEMADDED ||
133 nEvent == VCLEVENT_TOOLBOX_ALLITEMCHANGED ||
134 nEvent == VCLEVENT_MENUBARADDED ||
135 nEvent == 1
138 return 0L;
142 if (nEvent == VCLEVENT_APPLICATION_DATACHANGED )
144 DataChangedEvent* pData = reinterpret_cast<DataChangedEvent*>(_pEvt->GetData());
145 if ( pData && ((( pData->GetType() == DATACHANGED_SETTINGS ) ||
146 ( pData->GetType() == DATACHANGED_DISPLAY )) &&
147 ( pData->GetFlags() & SETTINGS_STYLE )))
149 OEnvLock aLock(*this);
151 // sal_uInt32 nCount = m_pImpl->m_aSections.size();
153 // send all Section Objects a 'tingle'
154 // maybe they need a change in format, color, etc
155 ::std::vector< uno::Reference< container::XChild > >::const_iterator aIter = m_pImpl->m_aSections.begin();
156 ::std::vector< uno::Reference< container::XChild > >::const_iterator aEnd = m_pImpl->m_aSections.end();
157 for (;aIter != aEnd; aIter++)
159 const uno::Reference<container::XChild> xChild (*aIter);
160 if (xChild.is())
162 uno::Reference<report::XSection> xSection(xChild, uno::UNO_QUERY);
163 if (xSection.is())
165 const sal_Int32 nCount = xSection->getCount();
166 for (sal_Int32 i = 0; i < nCount; ++i)
168 const uno::Any aObj = xSection->getByIndex(i);
169 uno::Reference < report::XReportComponent > xReportComponent(aObj, uno::UNO_QUERY);
170 if (xReportComponent.is())
172 m_aFormattedFieldBeautifier.handle(xReportComponent);
173 m_aFixedTextColor.handle(xReportComponent);
183 return 0L;
186 // -----------------------------------------------------------------------------
187 void OXReportControllerObserver::switchListening(const uno::Reference< uno::XInterface >& _rxObject, sal_Bool _bStartListening)
191 uno::Reference< beans::XPropertySet > xProps( _rxObject, uno::UNO_QUERY );
192 if ( xProps.is() )
194 if ( _bStartListening )
196 xProps->addPropertyChangeListener( ::rtl::OUString(), this );
198 else
200 xProps->removePropertyChangeListener( ::rtl::OUString(), this );
204 catch( const uno::Exception& )
206 DBG_UNHANDLED_EXCEPTION();
210 // XEventListener
211 void SAL_CALL OXReportControllerObserver::disposing(const lang::EventObject& e) throw( uno::RuntimeException )
213 (void) e;
214 // check if it's an object we have cached informations about
215 uno::Reference< beans::XPropertySet > xSourceSet(e.Source, uno::UNO_QUERY);
216 if ( xSourceSet.is() )
218 uno::Reference< report::XSection> xSection(xSourceSet,uno::UNO_QUERY);
219 if ( xSection.is() )
220 RemoveSection(xSection);
221 else
222 RemoveElement(xSourceSet);
226 void OXReportControllerObserver::Clear()
228 OEnvLock aLock(*this);
229 // sal_uInt32 nDebugValue = m_pImpl->m_aSections.size();
230 m_pImpl->m_aSections.clear();
233 // XPropertyChangeListener
234 void SAL_CALL OXReportControllerObserver::propertyChange(const beans::PropertyChangeEvent& _rEvent) throw(uno::RuntimeException)
236 (void) _rEvent;
237 ::osl::ClearableMutexGuard aGuard( m_pImpl->m_aMutex );
239 if ( IsLocked() )
240 return;
242 m_aFormattedFieldBeautifier.notifyPropertyChange(_rEvent);
243 m_aFixedTextColor.notifyPropertyChange(_rEvent);
246 // -----------------------------------------------------------------------------
247 void OXReportControllerObserver::Lock()
249 OSL_ENSURE(m_refCount,"Illegal call to dead object!");
250 osl_incrementInterlockedCount( &m_pImpl->m_nLocks );
252 void OXReportControllerObserver::UnLock()
254 OSL_ENSURE(m_refCount,"Illegal call to dead object!");
256 osl_decrementInterlockedCount( &m_pImpl->m_nLocks );
258 sal_Bool OXReportControllerObserver::IsLocked() const { return m_pImpl->m_nLocks != 0; }
260 //------------------------------------------------------------------------------
261 void OXReportControllerObserver::AddSection(const uno::Reference< report::XSection > & _xSection)
263 OEnvLock aLock(*this);
266 uno::Reference<container::XChild> xChild = _xSection.get();
267 m_pImpl->m_aSections.push_back(xChild);
268 uno::Reference< uno::XInterface > xInt(_xSection);
269 AddElement(xInt);
271 catch(const uno::Exception&)
273 DBG_UNHANDLED_EXCEPTION();
277 //------------------------------------------------------------------------------
278 void OXReportControllerObserver::RemoveSection(const uno::Reference< report::XSection > & _xSection)
280 OEnvLock aLock(*this);
283 uno::Reference<container::XChild> xChild(_xSection.get());
284 m_pImpl->m_aSections.erase(::std::remove(m_pImpl->m_aSections.begin(),m_pImpl->m_aSections.end(),
285 xChild), m_pImpl->m_aSections.end());
286 uno::Reference< uno::XInterface > xInt(_xSection);
287 RemoveElement(xInt);
289 catch(uno::Exception&)
291 DBG_UNHANDLED_EXCEPTION();
295 //------------------------------------------------------------------------------
296 void OXReportControllerObserver::TogglePropertyListening(const uno::Reference< uno::XInterface > & Element)
298 // listen at Container
299 uno::Reference< container::XIndexAccess > xContainer(Element, uno::UNO_QUERY);
300 if (xContainer.is())
302 uno::Reference< uno::XInterface > xInterface;
303 sal_Int32 nCount = xContainer->getCount();
304 for(sal_Int32 i = 0;i != nCount;++i)
306 xInterface.set(xContainer->getByIndex( i ),uno::UNO_QUERY);
307 TogglePropertyListening(xInterface);
311 uno::Reference< beans::XPropertySet > xSet(Element, uno::UNO_QUERY);
312 if (xSet.is())
314 if (!m_pImpl->m_bReadOnly)
315 xSet->addPropertyChangeListener( ::rtl::OUString(), this );
316 else
317 xSet->removePropertyChangeListener( ::rtl::OUString(), this );
322 //------------------------------------------------------------------------------
323 void OXReportControllerObserver::switchListening( const uno::Reference< container::XIndexAccess >& _rxContainer, bool _bStartListening ) SAL_THROW(())
325 OSL_PRECOND( _rxContainer.is(), "OXReportControllerObserver::switchListening: invalid container!" );
326 if ( !_rxContainer.is() )
327 return;
331 // also handle all children of this element
332 uno::Reference< uno::XInterface > xInterface;
333 sal_Int32 nCount = _rxContainer->getCount();
334 for(sal_Int32 i = 0;i != nCount;++i)
336 xInterface.set(_rxContainer->getByIndex( i ),uno::UNO_QUERY);
337 if ( _bStartListening )
338 AddElement( xInterface );
339 else
340 RemoveElement( xInterface );
343 // be notified of any changes in the container elements
344 uno::Reference< container::XContainer > xSimpleContainer( _rxContainer, uno::UNO_QUERY );
345 // OSL_ENSURE( xSimpleContainer.is(), "OXReportControllerObserver::switchListening: how are we expected to be notified of changes in the container?" );
346 if ( xSimpleContainer.is() )
348 if ( _bStartListening )
349 xSimpleContainer->addContainerListener( this );
350 else
351 xSimpleContainer->removeContainerListener( this );
354 catch( const uno::Exception& )
356 DBG_UNHANDLED_EXCEPTION();
360 //------------------------------------------------------------------------------
361 void OXReportControllerObserver::switchListening( const uno::Reference< uno::XInterface >& _rxObject, bool _bStartListening ) SAL_THROW(())
363 OSL_PRECOND( _rxObject.is(), "OXReportControllerObserver::switchListening: how should I listen at a NULL object?" );
367 if ( !m_pImpl->m_bReadOnly )
369 uno::Reference< beans::XPropertySet > xProps( _rxObject, uno::UNO_QUERY );
370 if ( xProps.is() )
372 if ( _bStartListening )
373 xProps->addPropertyChangeListener( ::rtl::OUString(), this );
374 else
375 xProps->removePropertyChangeListener( ::rtl::OUString(), this );
379 uno::Reference< util::XModifyBroadcaster > xBroadcaster( _rxObject, uno::UNO_QUERY );
380 if ( xBroadcaster.is() )
382 if ( _bStartListening )
383 xBroadcaster->addModifyListener( this );
384 else
385 xBroadcaster->removeModifyListener( this );
388 catch( const uno::Exception& )
390 DBG_UNHANDLED_EXCEPTION();
394 //------------------------------------------------------------------------------
395 void SAL_CALL OXReportControllerObserver::modified( const lang::EventObject& /*aEvent*/ ) throw (uno::RuntimeException)
397 // implSetModified();
400 //------------------------------------------------------------------------------
401 void OXReportControllerObserver::AddElement(const uno::Reference< uno::XInterface >& _rxElement )
403 // if ( !IsLocked() )
404 // {
405 m_aFormattedFieldBeautifier.notifyElementInserted(_rxElement);
406 m_aFixedTextColor.notifyElementInserted(_rxElement);
407 // }
409 // if it's a container, start listening at all elements
410 uno::Reference< container::XIndexAccess > xContainer( _rxElement, uno::UNO_QUERY );
411 if ( xContainer.is() )
412 switchListening( xContainer, true );
414 switchListening( _rxElement, true );
417 //------------------------------------------------------------------------------
418 void OXReportControllerObserver::RemoveElement(const uno::Reference< uno::XInterface >& _rxElement)
420 switchListening( _rxElement, false );
422 uno::Reference< container::XIndexAccess > xContainer( _rxElement, uno::UNO_QUERY );
423 if ( xContainer.is() )
424 switchListening( xContainer, false );
427 // -----------------------------------------------------------------------------
428 ::std::vector< uno::Reference< container::XChild> >::const_iterator OXReportControllerObserver::getSection(const uno::Reference<container::XChild>& _xContainer) const
430 ::std::vector< uno::Reference< container::XChild> >::const_iterator aFind = m_pImpl->m_aSections.end();
431 if ( _xContainer.is() )
433 aFind = ::std::find(m_pImpl->m_aSections.begin(),m_pImpl->m_aSections.end(),_xContainer);
435 if ( aFind == m_pImpl->m_aSections.end() )
437 uno::Reference<container::XChild> xParent(_xContainer->getParent(),uno::UNO_QUERY);
438 aFind = getSection(xParent);
441 return aFind;
443 // XContainerListener
444 //------------------------------------------------------------------------------
445 void SAL_CALL OXReportControllerObserver::elementInserted(const container::ContainerEvent& evt) throw(uno::RuntimeException)
447 ::vos::OClearableGuard aSolarGuard( Application::GetSolarMutex() );
448 ::osl::MutexGuard aGuard( m_pImpl->m_aMutex );
450 // neues Object zum lauschen
451 uno::Reference< uno::XInterface > xIface( evt.Element, uno::UNO_QUERY );
452 if ( xIface.is() )
454 AddElement(xIface);
458 //------------------------------------------------------------------------------
459 void SAL_CALL OXReportControllerObserver::elementReplaced(const container::ContainerEvent& evt) throw(uno::RuntimeException)
461 ::vos::OClearableGuard aSolarGuard( Application::GetSolarMutex() );
462 ::osl::MutexGuard aGuard( m_pImpl->m_aMutex );
464 uno::Reference< uno::XInterface > xIface(evt.ReplacedElement,uno::UNO_QUERY);
465 OSL_ENSURE(xIface.is(), "OXReportControllerObserver::elementReplaced: invalid container notification!");
466 RemoveElement(xIface);
468 xIface.set(evt.Element,uno::UNO_QUERY);
469 AddElement(xIface);
472 //------------------------------------------------------------------------------
473 void SAL_CALL OXReportControllerObserver::elementRemoved(const container::ContainerEvent& evt) throw(uno::RuntimeException)
475 ::vos::OClearableGuard aSolarGuard( Application::GetSolarMutex() );
476 ::osl::MutexGuard aGuard( m_pImpl->m_aMutex );
478 uno::Reference< uno::XInterface > xIface( evt.Element, uno::UNO_QUERY );
479 if ( xIface.is() )
481 RemoveElement(xIface);
486 } // namespace rptui