LibreOffice Module reportdesign (master) 1
ReportControllerObserver.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#include <sal/config.h>
21
22#include <map>
23
25#include <ReportController.hxx>
26#include <vcl/svapp.hxx>
27#include <vcl/settings.hxx>
28
30
31// DBG_UNHANDLED_EXCEPTION
33
34namespace rptui
35{
36
37 using namespace ::com::sun::star;
38
39typedef std::map<OUString, bool> AllProperties;
40typedef std::map<uno::Reference< beans::XPropertySet >, AllProperties> PropertySetInfoCache;
41
42
43
45 :m_nLocks(0)
46 ,m_aFormattedFieldBeautifier(_rController)
47 ,m_aFixedTextColor(_rController)
48 {
49
51 }
52
54 {
56 }
57
58
59 IMPL_LINK(OXReportControllerObserver, SettingsChanged, VclSimpleEvent&, _rEvt, void)
60 {
61 VclEventId nEvent = _rEvt.GetId();
62
63 if (nEvent != VclEventId::ApplicationDataChanged )
64 return;
65
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;
71
72 OEnvLock aLock(*this);
73
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)
77 {
78 if (xChild.is())
79 {
80 uno::Reference<report::XSection> xSection(xChild, uno::UNO_QUERY);
81 if (xSection.is())
82 {
83 const sal_Int32 nCount = xSection->getCount();
84 for (sal_Int32 i = 0; i < nCount; ++i)
85 {
86 const uno::Any aObj = xSection->getByIndex(i);
87 uno::Reference < report::XReportComponent > xReportComponent(aObj, uno::UNO_QUERY);
88 if (xReportComponent.is())
89 {
90 m_aFormattedFieldBeautifier.handle(xReportComponent);
91 m_aFixedTextColor.handle(xReportComponent);
92 }
93 }
94 }
95 }
96 }
97 }
98
99 // XEventListener
100 void SAL_CALL OXReportControllerObserver::disposing(const lang::EventObject& e)
101 {
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() )
105 {
106 uno::Reference< report::XSection> xSection(xSourceSet,uno::UNO_QUERY);
107 if ( xSection.is() )
108 RemoveSection(xSection);
109 else
110 RemoveElement(xSourceSet);
111 }
112 }
113
115 {
116 OEnvLock aLock(*this);
117 m_aSections.clear();
118 }
119
120 // XPropertyChangeListener
121 void SAL_CALL OXReportControllerObserver::propertyChange(const beans::PropertyChangeEvent& _rEvent)
122 {
123 osl::MutexGuard aGuard( m_aMutex );
124
125 if ( m_nLocks != 0 )
126 return;
127
130 }
131
132
134{
135 OSL_ENSURE(m_refCount,"Illegal call to dead object!");
136 osl_atomic_increment( &m_nLocks );
137}
138
140{
141 OSL_ENSURE(m_refCount,"Illegal call to dead object!");
142
143 osl_atomic_decrement( &m_nLocks );
144}
145
146void OXReportControllerObserver::AddSection(const uno::Reference< report::XSection > & _xSection)
147{
148 OEnvLock aLock(*this);
149 try
150 {
151 uno::Reference<container::XChild> xChild = _xSection;
152 m_aSections.push_back(xChild);
153 uno::Reference< uno::XInterface > xInt(_xSection);
154 AddElement(xInt);
155 }
156 catch(const uno::Exception&)
157 {
158 DBG_UNHANDLED_EXCEPTION("reportdesign");
159 }
160}
161
162
163void OXReportControllerObserver::RemoveSection(const uno::Reference< report::XSection > & _xSection)
164{
165 OEnvLock aLock(*this);
166 try
167 {
168 uno::Reference<container::XChild> xChild(_xSection);
169 m_aSections.erase(::std::remove(m_aSections.begin(), m_aSections.end(),
170 xChild), m_aSections.end());
171 uno::Reference< uno::XInterface > xInt(_xSection);
172 RemoveElement(xInt);
173 }
174 catch(uno::Exception&)
175 {
176 DBG_UNHANDLED_EXCEPTION("reportdesign");
177 }
178}
179
180
181void OXReportControllerObserver::switchListening( const uno::Reference< container::XIndexAccess >& _rxContainer, bool _bStartListening )
182{
183 OSL_PRECOND( _rxContainer.is(), "OXReportControllerObserver::switchListening: invalid container!" );
184 if ( !_rxContainer.is() )
185 return;
186
187 try
188 {
189 // also handle all children of this element
190 uno::Reference< uno::XInterface > xInterface;
191 sal_Int32 nCount = _rxContainer->getCount();
192 for(sal_Int32 i = 0;i != nCount;++i)
193 {
194 xInterface.set(_rxContainer->getByIndex( i ),uno::UNO_QUERY);
195 if ( _bStartListening )
196 AddElement( xInterface );
197 else
198 RemoveElement( xInterface );
199 }
200
201 // be notified of any changes in the container elements
202 uno::Reference< container::XContainer > xSimpleContainer( _rxContainer, uno::UNO_QUERY );
203 if ( xSimpleContainer.is() )
204 {
205 if ( _bStartListening )
206 xSimpleContainer->addContainerListener( this );
207 else
208 xSimpleContainer->removeContainerListener( this );
209 }
210 }
211 catch( const uno::Exception& )
212 {
213 DBG_UNHANDLED_EXCEPTION("reportdesign");
214 }
215}
216
217
218void OXReportControllerObserver::switchListening( const uno::Reference< uno::XInterface >& _rxObject, bool _bStartListening )
219{
220 OSL_PRECOND( _rxObject.is(), "OXReportControllerObserver::switchListening: how should I listen at a NULL object?" );
221
222 try
223 {
224 uno::Reference< beans::XPropertySet > xProps( _rxObject, uno::UNO_QUERY );
225 if ( xProps.is() )
226 {
227 if ( _bStartListening )
228 xProps->addPropertyChangeListener( OUString(), this );
229 else
230 xProps->removePropertyChangeListener( OUString(), this );
231 }
232
233 uno::Reference< util::XModifyBroadcaster > xBroadcaster( _rxObject, uno::UNO_QUERY );
234 if ( xBroadcaster.is() )
235 {
236 if ( _bStartListening )
237 xBroadcaster->addModifyListener( this );
238 else
239 xBroadcaster->removeModifyListener( this );
240 }
241 }
242 catch( const uno::Exception& )
243 {
244 DBG_UNHANDLED_EXCEPTION("reportdesign");
245 }
246}
247
248
249void SAL_CALL OXReportControllerObserver::modified( const lang::EventObject& /*aEvent*/ )
250{
251}
252
253
254void OXReportControllerObserver::AddElement(const uno::Reference< uno::XInterface >& _rxElement )
255{
258
259 // if it's a container, start listening at all elements
260 uno::Reference< container::XIndexAccess > xContainer( _rxElement, uno::UNO_QUERY );
261 if ( xContainer.is() )
262 switchListening( xContainer, true );
263
264 switchListening( _rxElement, true );
265}
266
267
268void OXReportControllerObserver::RemoveElement(const uno::Reference< uno::XInterface >& _rxElement)
269{
270 switchListening( _rxElement, false );
271
272 uno::Reference< container::XIndexAccess > xContainer( _rxElement, uno::UNO_QUERY );
273 if ( xContainer.is() )
274 switchListening( xContainer, false );
275}
276
277
278// XContainerListener
279
280void SAL_CALL OXReportControllerObserver::elementInserted(const container::ContainerEvent& evt)
281{
282 SolarMutexGuard aSolarGuard;
283 ::osl::MutexGuard aGuard( m_aMutex );
284
285 // new listener object
286 uno::Reference< uno::XInterface > xIface( evt.Element, uno::UNO_QUERY );
287 if ( xIface.is() )
288 {
289 AddElement(xIface);
290 }
291}
292
293
294void SAL_CALL OXReportControllerObserver::elementReplaced(const container::ContainerEvent& evt)
295{
296 SolarMutexGuard aSolarGuard;
297 ::osl::MutexGuard aGuard( m_aMutex );
298
299 uno::Reference< uno::XInterface > xIface(evt.ReplacedElement,uno::UNO_QUERY);
300 OSL_ENSURE(xIface.is(), "OXReportControllerObserver::elementReplaced: invalid container notification!");
301 RemoveElement(xIface);
302
303 xIface.set(evt.Element,uno::UNO_QUERY);
304 AddElement(xIface);
305}
306
307
308void SAL_CALL OXReportControllerObserver::elementRemoved(const container::ContainerEvent& evt)
309{
310 SolarMutexGuard aSolarGuard;
311 ::osl::MutexGuard aGuard( m_aMutex );
312
313 uno::Reference< uno::XInterface > xIface( evt.Element, uno::UNO_QUERY );
314 if ( xIface.is() )
315 {
316 RemoveElement(xIface);
317 }
318}
319
320
321} // namespace rptui
322
323
324/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
static void AddEventListener(const Link< VclSimpleEvent &, void > &rEventListener)
static void RemoveEventListener(const Link< VclSimpleEvent &, void > &rEventListener)
void notifyPropertyChange(const css::beans::PropertyChangeEvent &_rEvent) override
void notifyElementInserted(const css::uno::Reference< css::uno::XInterface > &_rxElement) override
void notifyElementInserted(const css::uno::Reference< css::uno::XInterface > &_rxElement) override
void notifyPropertyChange(const css::beans::PropertyChangeEvent &_rEvent) override
Create an object ob OUndoEnvLock locks the undo possibility As long as in the OUndoEnvLock scope,...
::std::vector< css::uno::Reference< css::container::XChild > > m_aSections
OXReportControllerObserver(const OXReportControllerObserver &)=delete
void AddSection(const css::uno::Reference< css::report::XSection > &_xSection)
void RemoveSection(const css::uno::Reference< css::report::XSection > &_xSection)
virtual void SAL_CALL elementInserted(const css::container::ContainerEvent &rEvent) override
void AddElement(const css::uno::Reference< css::uno::XInterface > &Element)
FormattedFieldBeautifier m_aFormattedFieldBeautifier
void switchListening(const css::uno::Reference< css::container::XIndexAccess > &_rxContainer, bool _bStartListening)
virtual void SAL_CALL elementReplaced(const css::container::ContainerEvent &rEvent) override
virtual void SAL_CALL disposing(const css::lang::EventObject &Source) override
virtual void SAL_CALL modified(const css::lang::EventObject &aEvent) override
virtual void SAL_CALL propertyChange(const css::beans::PropertyChangeEvent &evt) override
void RemoveElement(const css::uno::Reference< css::uno::XInterface > &Element)
virtual void SAL_CALL elementRemoved(const css::container::ContainerEvent &rEvent) override
int nCount
#define DBG_UNHANDLED_EXCEPTION(...)
ULONG m_refCount
Mutex aLock
std::unique_ptr< sal_Int32[]> pData
int i
std::map< OUString, bool > AllProperties
::std::map< Reference< XPropertySet >, ObjectInfo > PropertySetInfoCache
Definition: UndoEnv.cxx:85
IMPL_LINK(OAddFieldWindow, DragBeginHdl, bool &, rUnsetDragIcon, bool)
Definition: AddField.cxx:50
@ SettingsChanged
VclEventId