summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sfx2/source/notify/eventsupplier.cxx344
1 files changed, 294 insertions, 50 deletions
diff --git a/sfx2/source/notify/eventsupplier.cxx b/sfx2/source/notify/eventsupplier.cxx
index c91463429e38..5146c9bb1ecd 100644
--- a/sfx2/source/notify/eventsupplier.cxx
+++ b/sfx2/source/notify/eventsupplier.cxx
@@ -2,9 +2,9 @@
*
* $RCSfile: eventsupplier.cxx,v $
*
- * $Revision: 1.27 $
+ * $Revision: 1.28 $
*
- * last change: $Author: rt $ $Date: 2005-02-02 14:03:08 $
+ * last change: $Author: kz $ $Date: 2005-03-04 00:20:18 $
*
* The Contents of this file are made available subject to the terms of
* either of the following licenses
@@ -121,6 +121,8 @@
#define PROPERTYVALUE ::com::sun::star::beans::PropertyValue
#define UNO_QUERY ::com::sun::star::uno::UNO_QUERY
+namespace css = ::com::sun::star;
+
//--------------------------------------------------------------------------------------------------------
// --- XNameReplace ---
//--------------------------------------------------------------------------------------------------------
@@ -595,94 +597,336 @@ void SfxEvents_Impl::BlowUpMacro( const ANY& rEvent, ANY& rRet, SfxObjectShell*
}
}
+ModelCollectionEnumeration::ModelCollectionEnumeration(const css::uno::Reference< css::lang::XMultiServiceFactory >& xSMGR)
+ : ModelCollectionMutexBase( )
+ , m_xSMGR (xSMGR )
+ , m_pEnumerationIt (m_lModels.begin())
+{
+}
+
+ModelCollectionEnumeration::~ModelCollectionEnumeration()
+{
+}
+
+void ModelCollectionEnumeration::setModelList(const TModelList& rList)
+{
+ // SAFE ->
+ ::osl::ResettableMutexGuard aLock(m_aLock);
+ m_lModels = rList;
+ m_pEnumerationIt = m_lModels.begin();
+ aLock.clear();
+ // <- SAFE
+}
+
+sal_Bool SAL_CALL ModelCollectionEnumeration::hasMoreElements()
+ throw(css::uno::RuntimeException)
+{
+ // SAFE ->
+ ::osl::ResettableMutexGuard aLock(m_aLock);
+ return (m_pEnumerationIt != m_lModels.end());
+ // <- SAFE
+}
+
+css::uno::Any SAL_CALL ModelCollectionEnumeration::nextElement()
+ throw(css::container::NoSuchElementException,
+ css::lang::WrappedTargetException ,
+ css::uno::RuntimeException )
+{
+ // SAFE ->
+ ::osl::ResettableMutexGuard aLock(m_aLock);
+ if (m_pEnumerationIt == m_lModels.end())
+ throw css::container::NoSuchElementException(
+ ::rtl::OUString::createFromAscii("End of model enumeration reached."),
+ static_cast< css::container::XEnumeration* >(this));
+ css::uno::Reference< css::frame::XModel > xModel(*m_pEnumerationIt, UNO_QUERY);
+ ++m_pEnumerationIt;
+ aLock.clear();
+ // <- SAFE
+
+ return css::uno::makeAny(xModel);
+}
+
SFX_IMPL_XSERVICEINFO( SfxGlobalEvents_Impl, "com.sun.star.frame.GlobalEventBroadcaster", "com.sun.star.comp.sfx2.GlobalEventBroadcaster" )
SFX_IMPL_ONEINSTANCEFACTORY( SfxGlobalEvents_Impl );
-SfxGlobalEvents_Impl::SfxGlobalEvents_Impl( const com::sun::star::uno::Reference < ::com::sun::star::lang::XMultiServiceFactory >& xSmgr )
- : m_aInterfaceContainer( m_aMutex )
+//-----------------------------------------------------------------------------
+SfxGlobalEvents_Impl::SfxGlobalEvents_Impl( const com::sun::star::uno::Reference < ::com::sun::star::lang::XMultiServiceFactory >& xSMGR)
+ : ModelCollectionMutexBase( )
+ , m_xSMGR (xSMGR )
+ , m_aInterfaceContainer (m_aLock)
+ , pImp (0 )
{
m_refCount++;
-// pImp = new SfxEvents_Impl( NULL, this );
- pImp = new GlobalEventConfig();
- m_xEvents = pImp;
- m_xJobsBinding = REFERENCE< XJOBEXECUTOR >(xSmgr->createInstance(OUSTRING::createFromAscii("com.sun.star.task.JobExecutor")), UNO_QUERY);
- StartListening(*SFX_APP());
+ SFX_APP();
+ pImp = new GlobalEventConfig();
+ m_xEvents = pImp;
+ m_xJobsBinding = css::uno::Reference< css::task::XJobExecutor >(
+ xSMGR->createInstance(::rtl::OUString::createFromAscii("com.sun.star.task.JobExecutor")),
+ UNO_QUERY);
m_refCount--;
}
+//-----------------------------------------------------------------------------
SfxGlobalEvents_Impl::~SfxGlobalEvents_Impl()
{
}
-REFERENCE< XNAMEREPLACE > SAL_CALL SfxGlobalEvents_Impl::getEvents() throw( RUNTIMEEXCEPTION )
+//-----------------------------------------------------------------------------
+void SfxGlobalEvents_Impl::Notify( SfxBroadcaster& aBC, const SfxHint& aHint )
+{
+ SfxEventHint* pNamedHint = PTR_CAST(SfxEventHint, &aHint);
+ if (!pNamedHint)
+ return;
+
+ css::uno::Reference< css::document::XEventsSupplier > xSup;
+
+ ::rtl::OUString sName = SfxEventConfiguration::GetEventName_Impl(pNamedHint->GetEventId());
+ SfxObjectShell* pShell = pNamedHint->GetObjShell();
+ if (pShell)
+ xSup = css::uno::Reference< css::document::XEventsSupplier >(pShell->GetModel(), UNO_QUERY);
+
+ css::document::EventObject aEvent(xSup, sName);
+ notifyEvent(aEvent);
+}
+
+//-----------------------------------------------------------------------------
+css::uno::Reference< css::container::XNameReplace > SAL_CALL SfxGlobalEvents_Impl::getEvents()
+ throw(css::uno::RuntimeException)
{
+ // SAFE ->
+ ::osl::ResettableMutexGuard aLock(m_aLock);
return m_xEvents;
+ // <- SAFE
}
-void SAL_CALL SfxGlobalEvents_Impl::addEventListener( const REFERENCE< XDOCEVENTLISTENER >& xListener ) throw( RUNTIMEEXCEPTION )
+//-----------------------------------------------------------------------------
+void SAL_CALL SfxGlobalEvents_Impl::addEventListener(const css::uno::Reference< css::document::XEventListener >& xListener)
+ throw(css::uno::RuntimeException)
{
- m_aInterfaceContainer.addInterface( xListener );
+ // container is threadsafe
+ m_aInterfaceContainer.addInterface(xListener);
}
-void SAL_CALL SfxGlobalEvents_Impl::removeEventListener( const REFERENCE< XDOCEVENTLISTENER >& xListener ) throw( RUNTIMEEXCEPTION )
+//-----------------------------------------------------------------------------
+void SAL_CALL SfxGlobalEvents_Impl::removeEventListener(const css::uno::Reference< css::document::XEventListener >& xListener)
+ throw(css::uno::RuntimeException)
{
- m_aInterfaceContainer.removeInterface( xListener );
+ // container is threadsafe
+ m_aInterfaceContainer.removeInterface(xListener);
}
-void SfxGlobalEvents_Impl::Notify( SfxBroadcaster& aBC, const SfxHint& aHint )
+//-----------------------------------------------------------------------------
+void SAL_CALL SfxGlobalEvents_Impl::notifyEvent(const css::document::EventObject& aEvent)
+ throw(css::uno::RuntimeException)
{
- SfxEventHint* pNamedHint = PTR_CAST( SfxEventHint, &aHint );
- if ( pNamedHint )
- {
- OUSTRING aName = SfxEventConfiguration::GetEventName_Impl( pNamedHint->GetEventId() );
- REFERENCE < XEVENTSSUPPLIER > xSup;
- if ( pNamedHint->GetObjShell() )
- xSup = REFERENCE < XEVENTSSUPPLIER >( pNamedHint->GetObjShell()->GetModel(), UNO_QUERY );
-// else
-// xSup = (XEVENTSSUPPLIER*) this;
-
- DOCEVENTOBJECT aEvent( xSup, aName );
- notifyEvent(aEvent);
- }
+ implts_notifyJobExecution(aEvent);
+ implts_checkAndExecuteEventBindings(aEvent);
+ implts_notifyListener(aEvent);
+}
+
+//-----------------------------------------------------------------------------
+void SAL_CALL SfxGlobalEvents_Impl::disposing(const css::lang::EventObject& aEvent)
+ throw(css::uno::RuntimeException)
+{
+ css::uno::Reference< css::frame::XModel > xDoc(aEvent.Source, UNO_QUERY);
+
+ // SAFE ->
+ ::osl::ResettableMutexGuard aLock(m_aLock);
+ TModelList::iterator pIt = impl_searchDoc(xDoc);
+ if (pIt != m_lModels.end())
+ m_lModels.erase(pIt);
+ aLock.clear();
+ // <- SAFE
+}
+
+//-----------------------------------------------------------------------------
+sal_Bool SAL_CALL SfxGlobalEvents_Impl::has(const css::uno::Any& aElement)
+ throw (css::uno::RuntimeException)
+{
+ css::uno::Reference< css::frame::XModel > xDoc;
+ aElement >>= xDoc;
+
+ sal_Bool bHas = sal_False;
+
+ // SAFE ->
+ ::osl::ResettableMutexGuard aLock(m_aLock);
+ TModelList::iterator pIt = impl_searchDoc(xDoc);
+ if (pIt != m_lModels.end())
+ bHas = sal_True;
+ aLock.clear();
+ // <- SAFE
+
+ return bHas;
+}
+
+//-----------------------------------------------------------------------------
+void SAL_CALL SfxGlobalEvents_Impl::insert( const css::uno::Any& aElement )
+ throw (css::lang::IllegalArgumentException ,
+ css::container::ElementExistException,
+ css::uno::RuntimeException )
+{
+ css::uno::Reference< css::frame::XModel > xDoc;
+ aElement >>= xDoc;
+ if (!xDoc.is())
+ throw css::lang::IllegalArgumentException(
+ ::rtl::OUString::createFromAscii("Cant locate at least the model parameter."),
+ static_cast< css::container::XSet* >(this),
+ 0);
+
+ // SAFE ->
+ ::osl::ResettableMutexGuard aLock(m_aLock);
+ TModelList::iterator pIt = impl_searchDoc(xDoc);
+ if (pIt != m_lModels.end())
+ throw css::container::ElementExistException(
+ ::rtl::OUString(),
+ static_cast< css::container::XSet* >(this));
+ m_lModels.push_back(xDoc);
+ aLock.clear();
+ // <- SAFE
+
+ css::uno::Reference< css::document::XEventBroadcaster > xDocBroadcast(xDoc, UNO_QUERY);
+ if (xDocBroadcast.is())
+ xDocBroadcast->addEventListener(static_cast< css::document::XEventListener* >(this));
}
-void SAL_CALL SfxGlobalEvents_Impl::notifyEvent( const ::com::sun::star::document::EventObject& aEvent ) throw ( RUNTIMEEXCEPTION )
+//-----------------------------------------------------------------------------
+void SAL_CALL SfxGlobalEvents_Impl::remove( const css::uno::Any& aElement )
+ throw (css::lang::IllegalArgumentException ,
+ css::container::NoSuchElementException,
+ css::uno::RuntimeException )
{
- // Attention: This listener is a special one. It binds the global document events
- // to the generic job execution framework. It's a loose binding (using weak references).
- // So we hold this listener outside our normal listener container.
- // The implementation behind this job executor can be replaced ...
- // but we check for this undocumented interface!
- REFERENCE< XDOCEVENTLISTENER > xJobExecutor(m_xJobsBinding.get(), UNO_QUERY);
- if (xJobExecutor.is())
- xJobExecutor->notifyEvent(aEvent);
+ css::uno::Reference< css::frame::XModel > xDoc;
+ aElement >>= xDoc;
+ if (!xDoc.is())
+ throw css::lang::IllegalArgumentException(
+ ::rtl::OUString::createFromAscii("Cant locate at least the model parameter."),
+ static_cast< css::container::XSet* >(this),
+ 0);
+
+ // SAFE ->
+ ::osl::ResettableMutexGuard aLock(m_aLock);
+ TModelList::iterator pIt = impl_searchDoc(xDoc);
+ if (pIt == m_lModels.end())
+ throw css::container::NoSuchElementException(
+ ::rtl::OUString(),
+ static_cast< css::container::XSet* >(this));
+ m_lModels.erase(pIt);
+ aLock.clear();
+ // <- SAFE
+
+ css::uno::Reference< css::document::XEventBroadcaster > xDocBroadcast(xDoc, UNO_QUERY);
+ if (xDocBroadcast.is())
+ xDocBroadcast->removeEventListener(static_cast< css::document::XEventListener* >(this));
+}
+
+//-----------------------------------------------------------------------------
+css::uno::Reference< css::container::XEnumeration > SAL_CALL SfxGlobalEvents_Impl::createEnumeration()
+ throw (css::uno::RuntimeException)
+{
+ // SAFE ->
+ ::osl::ResettableMutexGuard aLock(m_aLock);
+ ModelCollectionEnumeration* pEnum = new ModelCollectionEnumeration(m_xSMGR);
+ pEnum->setModelList(m_lModels);
+ css::uno::Reference< css::container::XEnumeration > xEnum(
+ static_cast< css::container::XEnumeration* >(pEnum),
+ UNO_QUERY);
+ aLock.clear();
+ // <- SAFE
+
+ return xEnum;
+}
+//-----------------------------------------------------------------------------
+css::uno::Type SAL_CALL SfxGlobalEvents_Impl::getElementType()
+ throw (css::uno::RuntimeException)
+{
+ return ::getCppuType(static_cast< css::uno::Reference< css::frame::XModel >* >(NULL));
+}
+
+//-----------------------------------------------------------------------------
+sal_Bool SAL_CALL SfxGlobalEvents_Impl::hasElements()
+ throw (css::uno::RuntimeException)
+{
+ // SAFE ->
+ ::osl::ResettableMutexGuard aLock(m_aLock);
+ return (m_lModels.size()>0);
+ // <- SAFE
+}
+
+//-----------------------------------------------------------------------------
+void SfxGlobalEvents_Impl::implts_notifyJobExecution(const css::document::EventObject& aEvent)
+{
try
{
- ANY aAny = m_xEvents->getByName( aEvent.EventName );
- Execute( aAny, 0 );
+ // SAFE ->
+ ::osl::ResettableMutexGuard aLock(m_aLock);
+ css::uno::Reference< css::document::XEventListener > xJobExecutor(m_xJobsBinding.get(), UNO_QUERY);
+ aLock.clear();
+ // <- SAFE
+ if (xJobExecutor.is())
+ xJobExecutor->notifyEvent(aEvent);
}
- catch ( EXCEPTION& )
+ catch(const css::uno::RuntimeException& exRun)
+ { throw exRun; }
+ catch(const css::uno::Exception&)
+ {}
+}
+
+//-----------------------------------------------------------------------------
+void SfxGlobalEvents_Impl::implts_checkAndExecuteEventBindings(const css::document::EventObject& aEvent)
+{
+ try
{
+ // SAFE ->
+ ::osl::ResettableMutexGuard aLock(m_aLock);
+ css::uno::Reference< css::container::XNameReplace > xEvents = m_xEvents;
+ aLock.clear();
+ // <- SAFE
+
+ css::uno::Any aAny;
+ if (xEvents.is())
+ aAny = xEvents->getByName(aEvent.EventName);
+ Execute(aAny, 0);
}
+ catch(const css::uno::RuntimeException& exRun)
+ { throw exRun; }
+ catch(const css::uno::Exception&)
+ {}
+}
- ::cppu::OInterfaceIteratorHelper aIt( m_aInterfaceContainer );
- while( aIt.hasMoreElements() )
+//-----------------------------------------------------------------------------
+void SfxGlobalEvents_Impl::implts_notifyListener(const css::document::EventObject& aEvent)
+{
+ // container is threadsafe
+ ::cppu::OInterfaceIteratorHelper aIt(m_aInterfaceContainer);
+ while (aIt.hasMoreElements())
{
try
{
- ((XDOCEVENTLISTENER *)aIt.next())->notifyEvent( aEvent );
- }
- catch( RUNTIMEEXCEPTION& )
- {
- aIt.remove();
+ ((css::document::XEventListener*)aIt.next())->notifyEvent(aEvent);
}
+ catch(const css::uno::Exception&)
+ { aIt.remove(); }
}
}
-void SAL_CALL SfxGlobalEvents_Impl::disposing( const ::com::sun::star::lang::EventObject& aEvent ) throw ( RUNTIMEEXCEPTION )
+//-----------------------------------------------------------------------------
+// not threadsafe ... must be locked from outside!
+TModelList::iterator SfxGlobalEvents_Impl::impl_searchDoc(const css::uno::Reference< css::frame::XModel >& xModel)
{
- // not interesting for us.
- // It's an OneInstance-Service, which will be disposed be the global uno service manager only ...
+ if (!xModel.is())
+ return m_lModels.end();
+
+ TModelList::iterator pIt;
+ for ( pIt = m_lModels.begin();
+ pIt != m_lModels.end() ;
+ ++pIt )
+ {
+ css::uno::Reference< css::frame::XModel > xContainerDoc(*pIt, UNO_QUERY);
+ if (xContainerDoc == xModel)
+ break;
+ }
+
+ return pIt;
}