Get the style color and number just once
[LibreOffice.git] / reportdesign / source / ui / report / ReportControllerObserver.cxx
blob892f79872b1e8b02f9b37c5063a11beca3befec6
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 .
20 #include <sal/config.h>
22 #include <map>
24 #include <ReportControllerObserver.hxx>
25 #include <ReportController.hxx>
26 #include <vcl/svapp.hxx>
27 #include <vcl/settings.hxx>
29 #include <FormattedFieldBeautifier.hxx>
31 // DBG_UNHANDLED_EXCEPTION
32 #include <comphelper/diagnose_ex.hxx>
34 namespace rptui
37 using namespace ::com::sun::star;
39 typedef std::map<OUString, bool> AllProperties;
40 typedef std::map<uno::Reference< beans::XPropertySet >, AllProperties> PropertySetInfoCache;
44 OXReportControllerObserver::OXReportControllerObserver(const OReportController& _rController)
45 :m_nLocks(0)
46 ,m_aFormattedFieldBeautifier(_rController)
47 ,m_aFixedTextColor(_rController)
50 Application::AddEventListener(LINK( this, OXReportControllerObserver, SettingsChanged ) );
53 OXReportControllerObserver::~OXReportControllerObserver()
55 Application::RemoveEventListener(LINK( this, OXReportControllerObserver, SettingsChanged ) );
59 IMPL_LINK(OXReportControllerObserver, SettingsChanged, VclSimpleEvent&, _rEvt, void)
61 VclEventId nEvent = _rEvt.GetId();
63 if (nEvent != VclEventId::ApplicationDataChanged )
64 return;
66 DataChangedEvent* pData = static_cast<DataChangedEvent*>(static_cast<VclWindowEvent&>(_rEvt).GetData());
67 if ( !(pData && ((( pData->GetType() == DataChangedEventType::SETTINGS ) ||
68 ( pData->GetType() == DataChangedEventType::DISPLAY )) &&
69 ( pData->GetFlags() & AllSettingsFlags::STYLE ))))
70 return;
72 OEnvLock aLock(*this);
74 // send all Section Objects a 'tingle'
75 // maybe they need a change in format, color, etc
76 for (const uno::Reference<container::XChild>& xChild : m_aSections)
78 if (xChild.is())
80 uno::Reference<report::XSection> xSection(xChild, uno::UNO_QUERY);
81 if (xSection.is())
83 const sal_Int32 nCount = xSection->getCount();
84 for (sal_Int32 i = 0; i < nCount; ++i)
86 const uno::Any aObj = xSection->getByIndex(i);
87 uno::Reference < report::XReportComponent > xReportComponent(aObj, uno::UNO_QUERY);
88 if (xReportComponent.is())
90 m_aFormattedFieldBeautifier.handle(xReportComponent);
91 m_aFixedTextColor.handle(xReportComponent);
99 // XEventListener
100 void SAL_CALL OXReportControllerObserver::disposing(const lang::EventObject& e)
102 // check if it's an object we have cached information about
103 uno::Reference< beans::XPropertySet > xSourceSet(e.Source, uno::UNO_QUERY);
104 if ( xSourceSet.is() )
106 uno::Reference< report::XSection> xSection(xSourceSet,uno::UNO_QUERY);
107 if ( xSection.is() )
108 RemoveSection(xSection);
109 else
110 RemoveElement(xSourceSet);
114 void OXReportControllerObserver::Clear()
116 OEnvLock aLock(*this);
117 m_aSections.clear();
120 // XPropertyChangeListener
121 void SAL_CALL OXReportControllerObserver::propertyChange(const beans::PropertyChangeEvent& _rEvent)
123 osl::MutexGuard aGuard( m_aMutex );
125 if ( m_nLocks != 0 )
126 return;
128 m_aFormattedFieldBeautifier.notifyPropertyChange(_rEvent);
129 m_aFixedTextColor.notifyPropertyChange(_rEvent);
133 void OXReportControllerObserver::Lock()
135 OSL_ENSURE(m_refCount,"Illegal call to dead object!");
136 osl_atomic_increment( &m_nLocks );
139 void OXReportControllerObserver::UnLock()
141 OSL_ENSURE(m_refCount,"Illegal call to dead object!");
143 osl_atomic_decrement( &m_nLocks );
146 void OXReportControllerObserver::AddSection(const uno::Reference< report::XSection > & _xSection)
148 OEnvLock aLock(*this);
151 uno::Reference<container::XChild> xChild = _xSection;
152 m_aSections.push_back(xChild);
153 AddElement(_xSection);
155 catch(const uno::Exception&)
157 DBG_UNHANDLED_EXCEPTION("reportdesign");
162 void OXReportControllerObserver::RemoveSection(const uno::Reference< report::XSection > & _xSection)
164 OEnvLock aLock(*this);
167 uno::Reference<container::XChild> xChild(_xSection);
168 std::erase(m_aSections, xChild);
169 RemoveElement(_xSection);
171 catch(uno::Exception&)
173 DBG_UNHANDLED_EXCEPTION("reportdesign");
178 void OXReportControllerObserver::switchListening( const uno::Reference< container::XIndexAccess >& _rxContainer, bool _bStartListening )
180 OSL_PRECOND( _rxContainer.is(), "OXReportControllerObserver::switchListening: invalid container!" );
181 if ( !_rxContainer.is() )
182 return;
186 // also handle all children of this element
187 uno::Reference< uno::XInterface > xInterface;
188 sal_Int32 nCount = _rxContainer->getCount();
189 for(sal_Int32 i = 0;i != nCount;++i)
191 xInterface.set(_rxContainer->getByIndex( i ),uno::UNO_QUERY);
192 if ( _bStartListening )
193 AddElement( xInterface );
194 else
195 RemoveElement( xInterface );
198 // be notified of any changes in the container elements
199 uno::Reference< container::XContainer > xSimpleContainer( _rxContainer, uno::UNO_QUERY );
200 if ( xSimpleContainer.is() )
202 if ( _bStartListening )
203 xSimpleContainer->addContainerListener( this );
204 else
205 xSimpleContainer->removeContainerListener( this );
208 catch( const uno::Exception& )
210 DBG_UNHANDLED_EXCEPTION("reportdesign");
215 void OXReportControllerObserver::switchListening( const uno::Reference< uno::XInterface >& _rxObject, bool _bStartListening )
217 OSL_PRECOND( _rxObject.is(), "OXReportControllerObserver::switchListening: how should I listen at a NULL object?" );
221 uno::Reference< beans::XPropertySet > xProps( _rxObject, uno::UNO_QUERY );
222 if ( xProps.is() )
224 if ( _bStartListening )
225 xProps->addPropertyChangeListener( OUString(), this );
226 else
227 xProps->removePropertyChangeListener( OUString(), this );
230 uno::Reference< util::XModifyBroadcaster > xBroadcaster( _rxObject, uno::UNO_QUERY );
231 if ( xBroadcaster.is() )
233 if ( _bStartListening )
234 xBroadcaster->addModifyListener( this );
235 else
236 xBroadcaster->removeModifyListener( this );
239 catch( const uno::Exception& )
241 DBG_UNHANDLED_EXCEPTION("reportdesign");
246 void SAL_CALL OXReportControllerObserver::modified( const lang::EventObject& /*aEvent*/ )
251 void OXReportControllerObserver::AddElement(const uno::Reference< uno::XInterface >& _rxElement )
253 m_aFormattedFieldBeautifier.notifyElementInserted(_rxElement);
254 m_aFixedTextColor.notifyElementInserted(_rxElement);
256 // if it's a container, start listening at all elements
257 uno::Reference< container::XIndexAccess > xContainer( _rxElement, uno::UNO_QUERY );
258 if ( xContainer.is() )
259 switchListening( xContainer, true );
261 switchListening( _rxElement, true );
265 void OXReportControllerObserver::RemoveElement(const uno::Reference< uno::XInterface >& _rxElement)
267 switchListening( _rxElement, false );
269 uno::Reference< container::XIndexAccess > xContainer( _rxElement, uno::UNO_QUERY );
270 if ( xContainer.is() )
271 switchListening( xContainer, false );
275 // XContainerListener
277 void SAL_CALL OXReportControllerObserver::elementInserted(const container::ContainerEvent& evt)
279 SolarMutexGuard aSolarGuard;
280 ::osl::MutexGuard aGuard( m_aMutex );
282 // new listener object
283 uno::Reference< uno::XInterface > xIface( evt.Element, uno::UNO_QUERY );
284 if ( xIface.is() )
286 AddElement(xIface);
291 void SAL_CALL OXReportControllerObserver::elementReplaced(const container::ContainerEvent& evt)
293 SolarMutexGuard aSolarGuard;
294 ::osl::MutexGuard aGuard( m_aMutex );
296 uno::Reference< uno::XInterface > xIface(evt.ReplacedElement,uno::UNO_QUERY);
297 OSL_ENSURE(xIface.is(), "OXReportControllerObserver::elementReplaced: invalid container notification!");
298 RemoveElement(xIface);
300 xIface.set(evt.Element,uno::UNO_QUERY);
301 AddElement(xIface);
305 void SAL_CALL OXReportControllerObserver::elementRemoved(const container::ContainerEvent& evt)
307 SolarMutexGuard aSolarGuard;
308 ::osl::MutexGuard aGuard( m_aMutex );
310 uno::Reference< uno::XInterface > xIface( evt.Element, uno::UNO_QUERY );
311 if ( xIface.is() )
313 RemoveElement(xIface);
318 } // namespace rptui
321 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */