1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: UndoEnv.hxx,v $
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>
46 #include <tools/debug.hxx>
47 // DBG_UNHANDLED_EXCEPTION
48 #include <tools/diagnose_ex.h>
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
&);
65 const OReportController
& m_rReportController
;
66 ::std::vector
< uno::Reference
< container::XChild
> > m_aSections
;
67 ::osl::Mutex m_aMutex
;
68 oslInterlockedCount m_nLocks
;
71 OXReportControllerObserverImpl(const OReportController
& _rController
);
72 ~OXReportControllerObserverImpl();
75 // -----------------------------------------------------------------------------
77 OXReportControllerObserverImpl::OXReportControllerObserverImpl(const OReportController
& _rController
)
78 :m_rReportController(_rController
)
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
)
115 sal_Int32 nEvent
= _pEvt
->GetId();
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 ||
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
);
162 uno::Reference
<report::XSection
> xSection(xChild
, uno::UNO_QUERY
);
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
);
186 // -----------------------------------------------------------------------------
187 void OXReportControllerObserver::switchListening(const uno::Reference
< uno::XInterface
>& _rxObject
, sal_Bool _bStartListening
)
191 uno::Reference
< beans::XPropertySet
> xProps( _rxObject
, uno::UNO_QUERY
);
194 if ( _bStartListening
)
196 xProps
->addPropertyChangeListener( ::rtl::OUString(), this );
200 xProps
->removePropertyChangeListener( ::rtl::OUString(), this );
204 catch( const uno::Exception
& )
206 DBG_UNHANDLED_EXCEPTION();
211 void SAL_CALL
OXReportControllerObserver::disposing(const lang::EventObject
& e
) throw( uno::RuntimeException
)
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
);
220 RemoveSection(xSection
);
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
)
237 ::osl::ClearableMutexGuard
aGuard( m_pImpl
->m_aMutex
);
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
);
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
);
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
);
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
);
314 if (!m_pImpl
->m_bReadOnly
)
315 xSet
->addPropertyChangeListener( ::rtl::OUString(), this );
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() )
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
);
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 );
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
);
372 if ( _bStartListening
)
373 xProps
->addPropertyChangeListener( ::rtl::OUString(), this );
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 );
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() )
405 m_aFormattedFieldBeautifier
.notifyElementInserted(_rxElement
);
406 m_aFixedTextColor
.notifyElementInserted(_rxElement
);
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
);
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
);
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
);
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
);
481 RemoveElement(xIface
);