summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJörg Barfurth <jb@openoffice.org>2000-11-13 12:27:15 +0000
committerJörg Barfurth <jb@openoffice.org>2000-11-13 12:27:15 +0000
commit7ebe4146b2fef84d1c2e3fbc542c1919ccd0eb7b (patch)
tree63dbdfa289c9b5598e913d5250169679aa377af2
parentecdcb9d2a60874c8d05f8ea22cc56c7b4d698466 (diff)
Revised storage of notifiers
-rw-r--r--configmgr/source/api2/apinotifierimpl.cxx81
-rw-r--r--configmgr/source/api2/apitreeimplobj.cxx14
-rw-r--r--configmgr/source/api2/confignotifier.cxx55
-rw-r--r--configmgr/source/api2/confignotifier.hxx26
-rw-r--r--configmgr/source/api2/listenercontainer.cxx114
-rw-r--r--configmgr/source/api2/listenercontainer.hxx397
-rw-r--r--configmgr/source/api2/makefile.mk5
-rw-r--r--configmgr/source/api2/notifierimpl.hxx96
-rw-r--r--configmgr/source/inc/noderef.hxx12
-rw-r--r--configmgr/source/treemgr/noderef.cxx67
10 files changed, 693 insertions, 174 deletions
diff --git a/configmgr/source/api2/apinotifierimpl.cxx b/configmgr/source/api2/apinotifierimpl.cxx
index b323846deecb..ab0c99010696 100644
--- a/configmgr/source/api2/apinotifierimpl.cxx
+++ b/configmgr/source/api2/apinotifierimpl.cxx
@@ -2,9 +2,9 @@
*
* $RCSfile: apinotifierimpl.cxx,v $
*
- * $Revision: 1.1 $
+ * $Revision: 1.2 $
*
- * last change: $Author: jb $ $Date: 2000-11-07 14:34:32 $
+ * last change: $Author: jb $ $Date: 2000-11-13 13:26:28 $
*
* The Contents of this file are made available subject to the terms of
* either of the following licenses
@@ -95,20 +95,6 @@ namespace internal
using configuration::NodeVisitor;
/// helper for adding a Listener to all children of a node
- template <class Listener>
- class AddListener : public NodeVisitor
- {
- Reference<Listener> m_xListener;
- Notifier m_aNotifier;
- public:
- AddListener(Notifier const& aNotifier, Reference<Listener> const& xListener)
- : m_xListener(xListener)
- , m_aNotifier(aNotifier)
- {}
-
- virtual Result handle(NodeRef const& aNode); // NodeVisitor
- };
-
/// helper for adding a Listener to a named child of a node
template <class Listener>
class AddListenerByName : public NodeVisitor
@@ -128,21 +114,6 @@ namespace internal
/// helper for removing a Listener from all children of a node
template <class Listener>
- class RemoveListener : public NodeVisitor
- {
- Reference<Listener> m_xListener;
- Notifier m_aNotifier;
- public:
- RemoveListener(Notifier const& aNotifier, Reference<Listener> const& xListener)
- : m_xListener(xListener)
- , m_aNotifier(aNotifier)
- {}
-
- virtual Result handle(NodeRef const& aNode); // NodeVisitor
- };
-
- /// helper for removing a Listener from all children of a node
- template <class Listener>
class RemoveListenerByName : public NodeVisitor
{
Reference<Listener> m_xListener;
@@ -158,39 +129,26 @@ namespace internal
virtual Result handle(NodeRef const& aNode); // NodeVisitor
};
- /// add a Listener to a node
- template <class Listener>
- NodeVisitor::Result AddListener<Listener>::handle(NodeRef const& aNode)
- {
- m_aNotifier.add(aNode, m_xListener);
- return CONTINUE;
- }
/// add a Listener to a named node
template <class Listener>
NodeVisitor::Result AddListenerByName<Listener>::handle(NodeRef const& aNode)
{
if (aNode.getName() == m_aName)
{
- m_aNotifier.add(aNode, m_xListener);
+ m_aNotifier.addForOne(aNode, m_xListener);
return DONE;
}
else
return CONTINUE;
}
- /// remove a Listener from a node
- template <class Listener>
- NodeVisitor::Result RemoveListener<Listener>::handle(NodeRef const& aNode)
- {
- m_aNotifier.remove(aNode, m_xListener);
- return CONTINUE;
- }
+
/// remove a Listener from a named node
template <class Listener>
NodeVisitor::Result RemoveListenerByName<Listener>::handle(NodeRef const& aNode)
{
if (aNode.getName() == m_aName)
{
- m_aNotifier.remove(aNode, m_xListener);
+ m_aNotifier.removeForOne(aNode, m_xListener);
return DONE;
}
else
@@ -233,23 +191,25 @@ bool genericAddChildListener(NodeGroupInfoAccess& rNode, const Reference< Listen
using configuration::NodeVisitor;
using configuration::validateNodeName;
- GuardedNodeAccess aGuardedNode( rNode ); // guard access to children
- GuardedNotifier aGuardedNotifier( rNode ); // guard the notifier
-
- Tree aTree( aGuardedNode->getTree() );
- NodeRef aNode( aGuardedNode->getNode() );
-
if (sName.getLength() != 0)
{
+ GuardedNodeAccess aGuardedNode( rNode ); // guard access to children
+ GuardedNotifier aGuardedNotifier( rNode ); // guard the notifier
+
+ Tree aTree( aGuardedNode->getTree() );
+ NodeRef aNode( aGuardedNode->getNode() );
+
internal::AddListenerByName<Listener> aAdder( *aGuardedNotifier, xListener, validateNodeName(sName,aTree,aNode));
+
NodeVisitor::Result eFound = aTree.dispatchToChildren( aNode, aAdder );
return (eFound == NodeVisitor::DONE); // ok if NodeRef was found
}
else
{
- internal::AddListener<Listener> aAdder( *aGuardedNotifier,xListener);
- aTree.dispatchToChildren( aNode, aAdder );
+ GuardedNotifier aGuardedNotifier( rNode ); // guard the notifier
+
+ aGuardedNotifier->addForAll(rNode.getNode(), xListener);
return true; // always ok, as we addreess no specific NodeRef
}
@@ -276,6 +236,12 @@ bool genericRemoveChildListener(NodeGroupInfoAccess& rNode, const Reference< Lis
if (sName.getLength() != 0)
{
+ GuardedNodeAccess aGuardedNode( rNode ); // guard access to children
+ GuardedNotifier aGuardedNotifier( rNode ); // guard the notifier
+
+ Tree aTree( aGuardedNode->getTree() );
+ NodeRef aNode( aGuardedNode->getNode() );
+
internal::RemoveListenerByName<Listener> aRemover( *aGuardedNotifier, xListener, validateNodeName(sName,aTree,aNode) );
NodeVisitor::Result eFound = aTree.dispatchToChildren( aNode, aRemover );
@@ -283,8 +249,9 @@ bool genericRemoveChildListener(NodeGroupInfoAccess& rNode, const Reference< Lis
}
else
{
- internal::RemoveListener<Listener> aRemover( *aGuardedNotifier, xListener) ;
- aTree.dispatchToChildren( aNode, aRemover );
+ GuardedNotifier aGuardedNotifier( rNode ); // guard the notifier
+
+ aGuardedNotifier->removeForAll(rNode.getNode(), xListener);
return true; // always ok, as we addreess no specific NodeRef
}
diff --git a/configmgr/source/api2/apitreeimplobj.cxx b/configmgr/source/api2/apitreeimplobj.cxx
index 84dc5c0e8a0f..0f7a07c66aa7 100644
--- a/configmgr/source/api2/apitreeimplobj.cxx
+++ b/configmgr/source/api2/apitreeimplobj.cxx
@@ -2,9 +2,9 @@
*
* $RCSfile: apitreeimplobj.cxx,v $
*
- * $Revision: 1.4 $
+ * $Revision: 1.5 $
*
- * last change: $Author: dg $ $Date: 2000-11-13 12:14:15 $
+ * last change: $Author: jb $ $Date: 2000-11-13 13:26:28 $
*
* The Contents of this file are made available subject to the terms of
* either of the following licenses
@@ -104,7 +104,7 @@ ApiTreeImpl::ApiTreeImpl(UnoInterface* pInstance, Tree const& aTree, ApiTreeImpl
, m_aTree(aTree)
, m_rProvider(rParentTree.getProvider())
, m_pParentTree(0)
-, m_aNotifier(new NotifierImpl())
+, m_aNotifier(new NotifierImpl(aTree))
{
init(&rParentTree);
}
@@ -114,7 +114,7 @@ ApiTreeImpl::ApiTreeImpl(UnoInterface* pInstance, ApiProvider& rProvider, Tree c
, m_aTree(aTree)
, m_rProvider(rProvider)
, m_pParentTree(0)
-, m_aNotifier(new NotifierImpl())
+, m_aNotifier(new NotifierImpl(aTree))
{
OSL_ENSURE(!pParentTree || &rProvider == &pParentTree->m_rProvider,"WARNING: Parent tree has a different provider - trouble may be ahead");
init(pParentTree);
@@ -197,7 +197,7 @@ void ApiTreeImpl::implDisposeTree()
{
OSL_ENSURE(m_pParentTree == 0,"WARNING: Disposing a tree that still has a parent tree set");
- NotifierImpl::MultiContainer& aContainer = m_aNotifier->m_aListeners;
+ NotifierImpl::SpecialContainer& aContainer = m_aNotifier->m_aListeners;
if (aContainer.beginDisposing())
{
using configuration::NodeIDList;
@@ -217,7 +217,7 @@ void ApiTreeImpl::implDisposeTree()
rFactory.revokeElement( *it );
}
- aContainer.notifyDisposing( EventObject(getUnoInstance()) );
+ aContainer.notifyDisposing();
OSL_ASSERT(!aContainer.isDisposed());
@@ -245,7 +245,7 @@ void ApiTreeImpl::implDisposeNode(NodeRef const& aNode, UnoInterface* pInstance)
NodeID aNodeID(m_aTree,aNode);
- if (m_aNotifier->disposeNodeHelper( aNodeID,EventObject(pInstance)))
+ if (m_aNotifier->m_aListeners.disposeOne(aNodeID.toIndex()) )
{
getFactory().revokeElement(aNodeID);
}
diff --git a/configmgr/source/api2/confignotifier.cxx b/configmgr/source/api2/confignotifier.cxx
index d1468858035a..790cc562c119 100644
--- a/configmgr/source/api2/confignotifier.cxx
+++ b/configmgr/source/api2/confignotifier.cxx
@@ -2,9 +2,9 @@
*
* $RCSfile: confignotifier.cxx,v $
*
- * $Revision: 1.2 $
+ * $Revision: 1.3 $
*
- * last change: $Author: jb $ $Date: 2000-11-10 12:22:55 $
+ * last change: $Author: jb $ $Date: 2000-11-13 13:26:28 $
*
* The Contents of this file are made available subject to the terms of
* either of the following licenses
@@ -177,9 +177,9 @@ Broadcaster Notifier::makeBroadcaster(NodeChanges const& aChanges, bool bLocal)
}
// ---------------------------------------------------------------------------------------------------
-NotifierImpl::NotifierImpl()
+NotifierImpl::NotifierImpl(Tree const& aTree)
: m_aMutex()
-, m_aListeners(m_aMutex)
+, m_aListeners(m_aMutex, aTree.getContainedNodeCount(), KeyToIndex(aTree))
{
}
// ---------------------------------------------------------------------------------------------------
@@ -214,7 +214,7 @@ NotifierImpl::~NotifierImpl()
}
*/
// ---------------------------------------------------------------------------------------------------
-bool NotifierImpl::disposeNodeHelper(Key const& aNode, css::lang::EventObject const& aEvt) const
+/*bool NotifierImpl::disposeNodeHelper(Key const& aNode, css::lang::EventObject const& aEvt) const
{
using configuration::NodeIDList;
using configuration::getAllChildrenHelper;
@@ -285,6 +285,7 @@ bool NotifierImpl::disposeNodeHelper(Key const& aNode, css::lang::EventObject co
else
return false;
}
+*/
// ---------------------------------------------------------------------------------------------------
void Notifier::add(NodeRef const& aNode, uno::Reference< css::lang::XEventListener > const& xListener) const
@@ -308,17 +309,31 @@ void Notifier::add(NodeRef const& aNode, uno::Reference< css::util::XChangesList
}
// ---------------------------------------------------------------------------------------------------
-void Notifier::add(NodeRef const& aNode, uno::Reference< css::beans::XPropertyChangeListener > const& xListener) const
+void Notifier::addForAll(NodeRef const& aNode, uno::Reference< css::beans::XPropertyChangeListener > const& xListener) const
{
if (xListener.is())
- m_aImpl->add( NodeID(m_aTree,aNode), xListener );
+ m_aImpl->addForAll( NodeID(m_aTree,aNode), xListener );
}
// ---------------------------------------------------------------------------------------------------
-void Notifier::add(NodeRef const& aNode, uno::Reference< css::beans::XVetoableChangeListener > const& xListener) const
+void Notifier::addForOne(NodeRef const& aNode, uno::Reference< css::beans::XPropertyChangeListener > const& xListener) const
{
if (xListener.is())
- m_aImpl->add( NodeID(m_aTree,aNode), xListener );
+ m_aImpl->addNamed( NodeID(m_aTree,aNode), xListener );
+}
+// ---------------------------------------------------------------------------------------------------
+
+void Notifier::addForAll(NodeRef const& aNode, uno::Reference< css::beans::XVetoableChangeListener > const& xListener) const
+{
+ if (xListener.is())
+ m_aImpl->addForAll( NodeID(m_aTree,aNode), xListener );
+}
+// ---------------------------------------------------------------------------------------------------
+
+void Notifier::addForOne(NodeRef const& aNode, uno::Reference< css::beans::XVetoableChangeListener > const& xListener) const
+{
+ if (xListener.is())
+ m_aImpl->addNamed( NodeID(m_aTree,aNode), xListener );
}
// ---------------------------------------------------------------------------------------------------
@@ -362,17 +377,31 @@ void Notifier::remove(NodeRef const& aNode, uno::Reference< css::util::XChangesL
}
// ---------------------------------------------------------------------------------------------------
-void Notifier::remove(NodeRef const& aNode, uno::Reference< css::beans::XPropertyChangeListener > const& xListener) const
+void Notifier::removeForAll(NodeRef const& aNode, uno::Reference< css::beans::XPropertyChangeListener > const& xListener) const
{
if (xListener.is())
- m_aImpl->remove( NodeID(m_aTree,aNode), xListener );
+ m_aImpl->removeForAll( NodeID(m_aTree,aNode), xListener );
}
// ---------------------------------------------------------------------------------------------------
-void Notifier::remove(NodeRef const& aNode, uno::Reference< css::beans::XVetoableChangeListener > const& xListener) const
+void Notifier::removeForOne(NodeRef const& aNode, uno::Reference< css::beans::XPropertyChangeListener > const& xListener) const
{
if (xListener.is())
- m_aImpl->remove( NodeID(m_aTree,aNode), xListener );
+ m_aImpl->removeNamed( NodeID(m_aTree,aNode), xListener );
+}
+// ---------------------------------------------------------------------------------------------------
+
+void Notifier::removeForAll(NodeRef const& aNode, uno::Reference< css::beans::XVetoableChangeListener > const& xListener) const
+{
+ if (xListener.is())
+ m_aImpl->removeForAll( NodeID(m_aTree,aNode), xListener );
+}
+// ---------------------------------------------------------------------------------------------------
+
+void Notifier::removeForOne(NodeRef const& aNode, uno::Reference< css::beans::XVetoableChangeListener > const& xListener) const
+{
+ if (xListener.is())
+ m_aImpl->removeNamed( NodeID(m_aTree,aNode), xListener );
}
// ---------------------------------------------------------------------------------------------------
diff --git a/configmgr/source/api2/confignotifier.hxx b/configmgr/source/api2/confignotifier.hxx
index 201c6accbe59..aa5b849fb5c7 100644
--- a/configmgr/source/api2/confignotifier.hxx
+++ b/configmgr/source/api2/confignotifier.hxx
@@ -2,9 +2,9 @@
*
* $RCSfile: confignotifier.hxx,v $
*
- * $Revision: 1.2 $
+ * $Revision: 1.3 $
*
- * last change: $Author: jb $ $Date: 2000-11-10 12:22:55 $
+ * last change: $Author: jb $ $Date: 2000-11-13 13:26:28 $
*
* The Contents of this file are made available subject to the terms of
* either of the following licenses
@@ -171,10 +171,14 @@ namespace configmgr
/// Add a <type scope='com::sun::star::util'>XChangesListener</type> observing <var>aNode</var> and its descendants.
void add(NodeRef const& aNode, uno::Reference< css::util::XChangesListener > const& xListener) const;
- /// Add a <type scope='com::sun::star::beans'>XPropertyChangeListener</type> observing <var>aNode</var>.
- void add(NodeRef const& aNode, uno::Reference< css::beans::XPropertyChangeListener > const& xListener) const;
- /// Add a <type scope='com::sun::star::beans'>XVetoableChangeListener</type> constraining <var>aNode</var>.
- void add(NodeRef const& aNode, uno::Reference< css::beans::XVetoableChangeListener > const& xListener) const;
+ /// Add a <type scope='com::sun::star::beans'>XPropertyChangeListener</type> observing all children of <var>aNode</var>.
+ void addForAll(NodeRef const& aNode, uno::Reference< css::beans::XPropertyChangeListener > const& xListener) const;
+ /// Add a <type scope='com::sun::star::beans'>XPropertyChangeListener</type> observing only <var>aNode</var>.
+ void addForOne(NodeRef const& aNode, uno::Reference< css::beans::XPropertyChangeListener > const& xListener) const;
+ /// Add a <type scope='com::sun::star::beans'>XVetoableChangeListener</type> constraining all children of <var>aNode</var>.
+ void addForAll(NodeRef const& aNode, uno::Reference< css::beans::XVetoableChangeListener > const& xListener) const;
+ /// Add a <type scope='com::sun::star::beans'>XVetoableChangeListener</type> constraining only <var>aNode</var>.
+ void addForOne(NodeRef const& aNode, uno::Reference< css::beans::XVetoableChangeListener > const& xListener) const;
/** Add a <type scope='com::sun::star::beans'>XPropertiesChangeListener</type>
observing all properties of <var>aNode</var>.
@@ -196,10 +200,16 @@ namespace configmgr
void remove(NodeRef const& aNode, uno::Reference< css::util::XChangesListener > const& xListener) const;
/// Remove a <type scope='com::sun::star::beans'>XPropertyChangeListener</type> observing <var>aNode</var>.
- void remove(NodeRef const& aNode, uno::Reference< css::beans::XPropertyChangeListener > const& xListener) const;
+ void removeForAll(NodeRef const& aNode, uno::Reference< css::beans::XPropertyChangeListener > const& xListener) const;
+ /// Remove a <type scope='com::sun::star::beans'>XPropertyChangeListener</type> observing <var>aNode</var>.
+ void removeForOne(NodeRef const& aNode, uno::Reference< css::beans::XPropertyChangeListener > const& xListener) const;
/// Remove a <type scope='com::sun::star::beans'>XVetoableChangeListener</type> constraining <var>aNode</var>.
- void remove(NodeRef const& aNode, uno::Reference< css::beans::XVetoableChangeListener > const& xListener) const;
+ void removeForAll(NodeRef const& aNode, uno::Reference< css::beans::XVetoableChangeListener > const& xListener) const;
+ /// Remove a <type scope='com::sun::star::beans'>XVetoableChangeListener</type> constraining <var>aNode</var>.
+ void removeForOne(NodeRef const& aNode, uno::Reference< css::beans::XVetoableChangeListener > const& xListener) const;
+ /// Remove a <type scope='com::sun::star::beans'>XVetoableChangeListener</type> constraining <var>aNode</var>.
+ void remove(NodeRef const& aNode, uno::Reference< css::beans::XVetoableChangeListener > const& xListener) const;
/** Remove a <type scope='com::sun::star::beans'>XPropertiesChangeListener</type>
observing any properties of <var>aNode</var>.
*/
diff --git a/configmgr/source/api2/listenercontainer.cxx b/configmgr/source/api2/listenercontainer.cxx
new file mode 100644
index 000000000000..cff13daf15e6
--- /dev/null
+++ b/configmgr/source/api2/listenercontainer.cxx
@@ -0,0 +1,114 @@
+/*************************************************************************
+ *
+ * $RCSfile: listenercontainer.cxx,v $
+ *
+ * $Revision: 1.1 $
+ *
+ * last change: $Author: jb $ $Date: 2000-11-13 13:27:15 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#include "listenercontainer.hxx"
+
+#ifndef _COM_SUN_STAR_LANG_XEVENTLISTENER_HPP_
+#include <com/sun/star/lang/XEventListener.hpp>
+#endif
+
+#include <osl/diagnose.h>
+
+namespace configmgr
+{
+ namespace configapi
+ {
+/////////////////////////////////////////////////////////////////////////////////////////////
+
+//-----------------------------------------------------------------------------
+// class DisposeNotifier
+//-----------------------------------------------------------------------------
+
+void DisposeNotifier::appendAndClearContainer(ListenerContainer* pContainer)
+{
+ if (pContainer)
+ {
+ {
+ cppu::OInterfaceIteratorHelper aIterator(*pContainer);
+ while (aIterator.hasMoreElements())
+ {
+ aListeners.push_back(Listener::query(aIterator.next()));
+ }
+ }
+ pContainer->clear();
+ }
+}
+//-----------------------------------------------------------------------------
+void DisposeNotifier::notify()
+{
+ for(Listeners::iterator it = aListeners.begin(); it != aListeners.end(); ++it)
+ {
+ if (it->is())
+ {
+ (*it)->disposing(aEvent);
+ it->clear();
+ }
+ }
+ aListeners.clear();
+}
+
+//-----------------------------------------------------------------------------
+
+/////////////////////////////////////////////////////////////////////////////////////////////
+ }
+}
+
+
diff --git a/configmgr/source/api2/listenercontainer.hxx b/configmgr/source/api2/listenercontainer.hxx
index 39a8cb971ead..672660393d88 100644
--- a/configmgr/source/api2/listenercontainer.hxx
+++ b/configmgr/source/api2/listenercontainer.hxx
@@ -2,9 +2,9 @@
*
* $RCSfile: listenercontainer.hxx,v $
*
- * $Revision: 1.2 $
+ * $Revision: 1.3 $
*
- * last change: $Author: jb $ $Date: 2000-11-10 12:22:55 $
+ * last change: $Author: jb $ $Date: 2000-11-13 13:26:28 $
*
* The Contents of this file are made available subject to the terms of
* either of the following licenses
@@ -87,6 +87,9 @@ namespace configmgr
namespace uno = css::uno;
namespace lang = css::lang;
+ typedef uno::Type UnoType;
+ typedef uno::XInterface UnoInterface;
+ typedef uno::Reference<uno::XInterface> UnoInterfaceRef;
//-----------------------------------------------------------------------------
typedef cppu::OInterfaceContainerHelper ListenerContainer;
@@ -128,11 +131,40 @@ namespace configmgr
uno::Reference<Listener> m_xNext;
};
//-----------------------------------------------------------------------------
+ class DisposeNotifier
+ {
+ typedef uno::Reference< lang::XEventListener > Listener;
+ typedef std::vector< Listener > Listeners;
+ lang::EventObject aEvent;
+ Listeners aListeners;
+ public:
+ explicit
+ DisposeNotifier(UnoInterfaceRef const& aInterface) : aEvent(aInterface) {}
- template <class Key_, class KeyHash_, class KeyEq_>
- class MultiListenerContainer
+ void appendAndClearContainer(ListenerContainer* pContainer);
+ void notify();
+ };
+//-----------------------------------------------------------------------------
+ template <class Key_, class KeyHash_, class KeyEq_, class KeyToIndex_>
+ class SpecialListenerContainer
{
public:
+ typedef cppu::OMultiTypeInterfaceContainerHelper BasicContainerHelper;
+ struct BasicContainerInfo
+ {
+ UnoInterface* pInterface;
+ BasicContainerHelper* pContainer;
+ BasicContainerInfo() : pInterface(0), pContainer(0) {}
+ };
+ typedef std::vector<BasicContainerInfo> BasicContainerHelperArray;
+ typedef BasicContainerHelperArray::size_type Index;
+
+ typedef Key_ Key;
+ typedef cppu::OMultiTypeInterfaceContainerHelperVar< Key_,KeyHash_,KeyEq_ > SpecialContainerHelper;
+ typedef cppu::OBroadcastHelperVar< SpecialContainerHelper, Key > SpecialBroadcastHelper;
+ typedef std::vector<Key> KeyList;
+
+ public:
/**
* Create a container of interface containers.
*
@@ -140,19 +172,21 @@ namespace configmgr
* The lifetime must be longer than the lifetime
* of this object.
*/
- MultiListenerContainer(osl::Mutex& rMutex)
- : m_aBroadcastHelper(rMutex)
+ SpecialListenerContainer(osl::Mutex& rMutex, Index nCount, KeyToIndex_ aMapper)
+ : m_aSpecialHelper(rMutex)
+ , m_aContainers(nCount)
, m_bDisposeLock(false)
+ , m_aMapper(aMapper)
{}
- ~MultiListenerContainer()
+ ~SpecialListenerContainer()
{
OSL_ENSURE(isDisposed(), "ERROR: Object was not disposed properly");
if (m_bDisposeLock) mutex().release();
}
public:
/// get the mutex thatthis object uses
- osl::Mutex& mutex() const { return m_aBroadcastHelper.rMutex; }
+ osl::Mutex& mutex() const { return m_aSpecialHelper.rMutex; }
/**
* check whether this is disposed or still alive
@@ -172,11 +206,69 @@ namespace configmgr
/// return whether the object is completely disposed
bool isDisposed()volatile const throw();
+ /// return whether the object is present in this container
+ bool isAvailable(Index nIndex) const throw()
+ {
+ osl::MutexGuard aGuard(mutex());
+ return nIndex < m_aContainers.size() && m_aContainers[nIndex].pInterface;
+ }
+
+ Index getSize() const
+ {
+ osl::MutexGuard aGuard(mutex());
+ return m_aContainers.size();
+ }
+
+ /// return the interface associated with an index
+ void setObjectAt(Index nIndex, UnoInterface* pInterface)
+ {
+ osl::MutexGuard aGuard(mutex());
+ OSL_ENSHURE( !isDisposed(), "object is disposed" );
+
+ if (isAlive())
+ {
+ OSL_ENSURE( nIndex < m_aContainers.size(), " Invalid Index into Notifier");
+ OSL_ENSURE( pInterface, "Invalid NULL Interface passed into Notifier");
+
+ if ( nIndex < m_aContainers.size() && pInterface != NULL)
+ {
+ OSL_ENSURE( m_aContainers[nIndex].pInterface == NULL, "Interface already set");
+ if (m_aContainers[nIndex].pInterface == NULL)
+ m_aContainers[nIndex].pInterface = pInterface;
+ }
+ }
+ }
+
+
+ /// return the interface associated with an index
+ UnoInterfaceRef getObjectAt(Index nIndex) const
+ {
+ osl::MutexGuard aGuard(mutex());
+ UnoInterfaceRef aRet( nIndex < m_aContainers.size() ? m_aContainers[nIndex].pInterface : 0 );
+ return xRet;
+ }
+
+ /// return the interface associated with an index
+ UnoInterfaceRef getObjectForKey(Key const& aKey ) const
+ {
+ osl::MutexGuard aGuard(mutex());
+ Index nIndex = m_aMapper.findIndexForKey(aKey);
+ UnoInterfaceRef xRet( nIndex < m_aContainers.size() ? m_aContainers[nIndex].pInterface : 0 );
+ return xRet;
+ }
+
/**
* Call disposing on all object in all the containers that
* support XEventListener. Then clear the container.
*/
- void dispose( const lang::EventObject & rEvt ) throw(uno::RuntimeException);
+ bool disposeAll() throw(uno::RuntimeException);
+
+ /**
+ * Call disposing on all object in all the container for anIndex
+ * and in the containers for the associated indices
+ * support XEventListener. Then clear the container.
+ */
+ bool disposeOne( Index anIndex ) throw(uno::RuntimeException);
/**
* Start disposing this object, leave the mutex locked for dispose processing
@@ -196,28 +288,72 @@ namespace configmgr
* @return <FALSE/>
* if disposing had already been started before
*/
- void notifyDisposing( const lang::EventObject & rEvt ) throw(uno::RuntimeException);
+ void notifyDisposing() throw(uno::RuntimeException);
/// mark the end of the dispose processing
void endDisposing() throw();
public:
/**
- * Return the container created under this key.
+ * Return the specuial container created under this key.
* @return the container created under this key. If the container
* was not created, null was returned.
*/
- ListenerContainer * getContainer( const Key_ & aKey) const
- { return m_aBroadcastHelper.aLC.getContainer(aKey); }
+ ListenerContainer * getSpecialContainer( const Key_ & aKey) const
+ { return m_aSpecialHelper.aLC.getContainer(aKey); }
/**
- * Insert an element in the container specified with the key. The position is not specified.
+ * Return the containerhelper created under this index.
+ * @return the container helper created under this key. If the container helper
+ * was not created, null was returned.
+ */
+ BasicContainerHelper * getContainerHelper( Index nIndex) const
+ {
+ osl::MutexGuard aGuard(mutex());
+ return (nIndex < m_aContainers.size()) ? m_aContainers[nIndex].pContainer : 0 );
+ }
+ /**
+ * Return the container for the given type created under this index.
+ * @return the container created under this key. If the container
+ * was not created, null was returned.
+ */
+ ListenerContainer * getContainer( Index nIndex, const UnoType & aType) const
+ {
+ osl::MutexGuard aGuard(mutex());
+ BasicContainerHelper* pContainer = (nIndex < m_aContainers.size()) ? m_aContainers[nIndex].pContainer : 0 );
+
+ return pContainer ? pContainer->getContainer(aType) : 0;
+ }
+
+ /**
+ * Insert an element in the container specified with the index and type. The position is not specified.
+ * The interface at the given index must be set already.
+ * @param aKey the id of the container.
+ * @param xListener the added interface. It is allowed to insert null or
+ * the same pointer more than once.
+ * @return the new count of elements in the container (or 0 if the object is ready being disposed).
+ */
+ sal_Int32 addListener( Index nIndex, const UnoType& aType, uno::Reference< lang::XEventListener > const& xListener) throw(uno::RuntimeException);
+
+ /**
+ * Remove an element from the container specified with the index and type.
+ * It uses the equal definition of uno objects to remove the interfaces.
+ * @param aKey the id of the container.
+ * @param xListener the removed interface.
+ * @return the new count of elements in the container (or 0 if the object is ready being disposed).
+ */
+ sal_Int32 removeListener( Index nIndex, const UnoType& aType, uno::Reference< lang::XEventListener > const& xListener) throw(uno::RuntimeException);
+
+
+ /**
+ * Insert an element in the special container specified with the key. The position is not specified.
+ * The interface at the given index must be set already.
* @param aKey the id of the container.
* @param xListener the added interface. It is allowed to insert null or
* the same pointer more than once.
* @return the new count of elements in the container (or 0 if the object is ready being disposed).
*/
- sal_Int32 addListener( const Key_& aKey, uno::Reference< lang::XEventListener > const& xListener) throw(uno::RuntimeException);
+ sal_Int32 addSpecialListener( const Key_& aKey, uno::Reference< lang::XEventListener > const& xListener) throw(uno::RuntimeException);
/**
* Remove an element from the container specified with the key.
@@ -226,71 +362,102 @@ namespace configmgr
* @param xListener the removed interface.
* @return the new count of elements in the container (or 0 if the object is ready being disposed).
*/
- sal_Int32 removeListener( const Key_& aKey, uno::Reference< lang::XEventListener > const& xListener) throw(uno::RuntimeException);
+ sal_Int32 removeSpecialListener( const Key_& aKey, uno::Reference< lang::XEventListener > const& xListener) throw(uno::RuntimeException);
- public:
- typedef Key_ Key;
- typedef KeyHash_ KeyHash;
- typedef KeyEq_ KeyEq;
- typedef cppu::OMultiTypeInterfaceContainerHelperVar< Key_, KeyHash_, KeyEq_ > ContainerHelper;
- typedef cppu::OBroadcastHelperVar< ContainerHelper, Key > BroadcastHelper;
private:
- BroadcastHelper m_aBroadcastHelper;
+ void implFillDisposer(DisposeNotifier& aNotifier, Index nIndex);
+
+ SpecialBroadcastHelper m_aSpecialHelper;
+ BasicContainerHelperArray m_aContainers;
+ KeyToIndex_ m_aMapper;
bool m_bDisposeLock;
};
//-----------------------------------------------------------------------------
/////////////////////////////////////////////////////////////////////////////////////////////
- template <class Key_, class KeyHash_, class KeyEq_>
- bool MultiListenerContainer<Key_,KeyHash_,KeyEq_>::checkAlive(uno::XInterface* pObject) volatile const throw(lang::DisposedException)
+ template <class Key_, class KeyHash_, class KeyEq_, class KeyToIndex_>
+ bool SpecialListenerContainer<Key_,KeyHash_,KeyEq_, KeyToIndex_>::checkAlive(uno::XInterface* pObject) volatile const throw(lang::DisposedException)
{
- bool bAlive = !m_aBroadcastHelper.bInDispose;
- if (m_aBroadcastHelper.bDisposed)
+ bool bAlive = !m_aSpecialHelper.bInDispose;
+ if (m_aSpecialHelper.bDisposed)
{
throw lang::DisposedException(OUString(RTL_CONSTASCII_USTRINGPARAM("The object has already been disposed")),pObject);
}
return bAlive;
}
//-----------------------------------------------------------------------------
- template <class Key_, class KeyHash_, class KeyEq_>
+ template <class Key_, class KeyHash_, class KeyEq_, class KeyToIndex_>
inline
- bool MultiListenerContainer<Key_,KeyHash_,KeyEq_>::isAlive() volatile const throw()
+ bool SpecialListenerContainer<Key_,KeyHash_,KeyEq_, KeyToIndex_>::isAlive() volatile const throw()
{
- return !m_aBroadcastHelper.bInDispose && !m_aBroadcastHelper.bDisposed;
+ return !m_aSpecialHelper.bInDispose && !m_aSpecialHelper.bDisposed;
}
//-----------------------------------------------------------------------------
- template <class Key_, class KeyHash_, class KeyEq_>
+ template <class Key_, class KeyHash_, class KeyEq_, class KeyToIndex_>
inline
- bool MultiListenerContainer<Key_,KeyHash_,KeyEq_>::isDisposing() volatile const throw()
+ bool SpecialListenerContainer<Key_,KeyHash_,KeyEq_, KeyToIndex_>::isDisposing() volatile const throw()
{
- return !!m_aBroadcastHelper.bInDispose;
+ return !!m_aSpecialHelper.bInDispose;
}
//-----------------------------------------------------------------------------
- template <class Key_, class KeyHash_, class KeyEq_>
+ template <class Key_, class KeyHash_, class KeyEq_, class KeyToIndex_>
inline
- bool MultiListenerContainer<Key_,KeyHash_,KeyEq_>::isDisposed() volatile const throw()
+ bool SpecialListenerContainer<Key_,KeyHash_,KeyEq_, KeyToIndex_>::isDisposed() volatile const throw()
{
- return !!m_aBroadcastHelper.bDisposed;
+ return !!m_aSpecialHelper.bDisposed;
}
//-----------------------------------------------------------------------------
- template <class Key_, class KeyHash_, class KeyEq_>
- void MultiListenerContainer<Key_,KeyHash_,KeyEq_>::dispose(const lang::EventObject & rEvt) throw(uno::RuntimeException)
+ template <class Key_, class KeyHash_, class KeyEq_, class KeyToIndex_>
+ bool SpecialListenerContainer<Key_,KeyHash_,KeyEq_, KeyToIndex_>::disposeAll() throw(uno::RuntimeException)
{
if (beginDisposing())
{
- notifyDisposing( rEvt );
+ notifyDisposing();
endDisposing();
+ return true;
}
+ else
+ return false;
}
//-----------------------------------------------------------------------------
- template <class Key_, class KeyHash_, class KeyEq_>
- bool MultiListenerContainer<Key_,KeyHash_,KeyEq_>::beginDisposing() throw()
+ template <class Key_, class KeyHash_, class KeyEq_, class KeyToIndex_>
+ bool SpecialListenerContainer<Key_,KeyHash_,KeyEq_, KeyToIndex_>::disposeOne(Index nIndex) throw(uno::RuntimeException)
+ {
+ OSL_ENSURE(!isDisposed(),"Object is already disposed in toto");
+
+ osl::ClearableMutexGuard aGuard(mutex());
+
+ if (isAlive())
+ {
+ if (nIndex < m_aContainers.size())
+ {
+ if (UnoInterface* pObject = m_aContainers[nIndex].pInterface)
+ {
+ DisposeNotifier aNotifier(pObject);
+
+ implFillDisposer(aNotifier, nIndex);
+ m_aContainers[nIndex].pInterface = 0;
+ delete m_aContainers[nIndex].pContainer;
+
+ aGuard.clear();
+
+ aNotifier.notify();
+ }
+ }
+ return true;
+ }
+ else
+ return false;
+ }
+//-----------------------------------------------------------------------------
+ template <class Key_, class KeyHash_, class KeyEq_, class KeyToIndex_>
+ bool SpecialListenerContainer<Key_,KeyHash_,KeyEq_, KeyToIndex_>::beginDisposing() throw()
{
osl::MutexGuard aGuard( mutex() );
if (isAlive())
{
mutex().acquire();
- m_aBroadcastHelper.bInDispose = sal_True;
+ m_aSpecialHelper.bInDispose = sal_True;
m_bDisposeLock = true;
return true;
@@ -298,24 +465,50 @@ namespace configmgr
return false;
}
//-----------------------------------------------------------------------------
- template <class Key_, class KeyHash_, class KeyEq_>
- void MultiListenerContainer<Key_,KeyHash_,KeyEq_>::notifyDisposing(const lang::EventObject & rEvt) throw(uno::RuntimeException)
+ template <class Key_, class KeyHash_, class KeyEq_, class KeyToIndex_>
+ void SpecialListenerContainer<Key_,KeyHash_,KeyEq_, KeyToIndex_>::notifyDisposing() throw(uno::RuntimeException)
{
OSL_ENSURE(isDisposing(),"Disposing isn't in progress on this object");
OSL_ENSURE(m_bDisposeLock,"Duplicate call for dispose notification or disposing is not taking place");
if (m_bDisposeLock)
{
- OSL_ASSERT(m_aBroadcastHelper.bInDispose);
+ OSL_ASSERT(m_aSpecialHelper.bInDispose);
+
+ lang::EventObject aBaseEvt;
+ std::vector<DisposeNotifier> aNotifiers;
+
+ if (Index size = m_aContainers.size())
+ {
+ aNotifiers.reserve(m_aContainers.size());
+
+ aBaseEvt.Source = m_aContainers[0].pInterface;
+ for(Index ix = 0; ix < size; ++ix)
+ {
+ if (m_aContainers[ix].pInterface)
+ {
+ aNotifiers.push_back(DisposeNotifier(m_aContainers[ix].pInterface));
+ implFillDisposer(aNotifiers.back(), ix);
+ m_aContainers[ix].pInterface = 0;
+ delete m_aContainers[ix].pContainer;
+ }
+ }
+ }
+
m_bDisposeLock = false;
mutex().release();
- m_aBroadcastHelper.aLC.disposeAndClear( rEvt );
+ for(Index jx = 0, count = aNotifiers.size(); jx < count; ++jx)
+ {
+ aNotifiers[jx].notify();
+ }
+ // in case we missed something
+ m_aSpecialHelper.aLC.disposeAndClear( aBaseEvt );
}
}
//-----------------------------------------------------------------------------
- template <class Key_, class KeyHash_, class KeyEq_>
- void MultiListenerContainer<Key_,KeyHash_,KeyEq_>::endDisposing() throw()
+ template <class Key_, class KeyHash_, class KeyEq_, class KeyToIndex_>
+ void SpecialListenerContainer<Key_,KeyHash_,KeyEq_, KeyToIndex_>::endDisposing() throw()
{
OSL_ENSURE(isDisposing(),"Disposing isn't in progress on this object");
@@ -323,8 +516,8 @@ namespace configmgr
{
OSL_ENSURE(!m_bDisposeLock,"Did you forget to notify ?");
- m_aBroadcastHelper.bDisposed = sal_True;
- m_aBroadcastHelper.bInDispose = sal_False;
+ m_aSpecialHelper.bDisposed = sal_True;
+ m_aSpecialHelper.bInDispose = sal_False;
if (m_bDisposeLock)
{
@@ -334,34 +527,122 @@ namespace configmgr
}
}
//-----------------------------------------------------------------------------
- template <class Key_, class KeyHash_, class KeyEq_>
- sal_Int32 MultiListenerContainer<Key_,KeyHash_,KeyEq_>::addListener( const Key_& aKey, const uno::Reference< lang::XEventListener > & xListener ) throw(uno::RuntimeException)
+ template <class Key_, class KeyHash_, class KeyEq_, class KeyToIndex_>
+ sal_Int32 SpecialListenerContainer<Key_,KeyHash_,KeyEq_, KeyToIndex_>::addListener( Index nIndex, const UnoType& aType, const uno::Reference< lang::XEventListener > & xListener ) throw(uno::RuntimeException)
{
osl::MutexGuard aGuard( mutex() );
OSL_ENSHURE( !isDisposing(), "do not add listeners in the dispose call" );
OSL_ENSHURE( !isDisposed(), "object is disposed" );
if ( isAlive() )
- return m_aBroadcastHelper.aLC.addInterface(aKey,xListener);
+ {
+ if ( nIndex < m_aContainers.size() && m_aContainers[nIndex].pInterface )
+ {
+ if (m_aContainers[nIndex].pContainer == 0)
+ m_aContainers[nIndex].pContainer = new BasicContainerHelper(mutex());
- else
- return 0;
+ return m_aContainers[nIndex].pContainer->addInterface(aType,xListener);
+ }
+ OSL_ENSURE(false, "Invalid index or interface not set");
+ }
+ return 0;
+ }
+//-----------------------------------------------------------------------------
+ template <class Key_, class KeyHash_, class KeyEq_, class KeyToIndex_>
+ sal_Int32 SpecialListenerContainer<Key_,KeyHash_,KeyEq_, KeyToIndex_>::addSpecialListener( const Key_& aKey, const uno::Reference< lang::XEventListener > & xListener ) throw(uno::RuntimeException)
+ {
+ osl::MutexGuard aGuard( mutex() );
+ OSL_ENSHURE( !isDisposing(), "do not add listeners in the dispose call" );
+ OSL_ENSHURE( !isDisposed(), "object is disposed" );
+
+ if ( isAlive() )
+ {
+ Index nIndex = m_aMapper.findIndexForKey(aKey);
+ if ( nIndex < m_aContainers.size() && m_aContainers[nIndex].pInterface )
+ {
+ return m_aSpecialHelper.aLC.addInterface(aKey,xListener);
+ }
+ OSL_ENSURE(false, "Invalid index or interface not set");
+ }
+ return 0;
+ }
+//-----------------------------------------------------------------------------
+
+ template <class Key_, class KeyHash_, class KeyEq_, class KeyToIndex_>
+ sal_Int32 SpecialListenerContainer<Key_,KeyHash_,KeyEq_, KeyToIndex_>::removeListener( Index nIndex, const UnoType& aType, const uno::Reference< lang::XEventListener > & xListener ) throw(uno::RuntimeException)
+ {
+ osl::MutexGuard aGuard( mutex() );
+ OSL_ENSHURE( !isDisposed(), "object is disposed" );
+
+ if ( isAlive() )
+ {
+ if ( nIndex < m_aContainers.size() && m_aContainers[nIndex].pContainer )
+ {
+ return m_aContainers[nIndex].pContainer->addInterface(aType,xListener);
+ }
+ }
+ return 0;
}
//-----------------------------------------------------------------------------
- template <class Key_, class KeyHash_, class KeyEq_>
- sal_Int32 MultiListenerContainer<Key_,KeyHash_,KeyEq_>::removeListener( const Key_& aKey, const uno::Reference< lang::XEventListener > & xListener ) throw(uno::RuntimeException)
+ template <class Key_, class KeyHash_, class KeyEq_, class KeyToIndex_>
+ sal_Int32 SpecialListenerContainer<Key_,KeyHash_,KeyEq_, KeyToIndex_>::removeSpecialListener( const Key_& aKey, const uno::Reference< lang::XEventListener > & xListener ) throw(uno::RuntimeException)
{
osl::MutexGuard aGuard( mutex() );
OSL_ENSHURE( !isDisposed(), "object is disposed" );
if ( isAlive() )
- m_aBroadcastHelper.aLC.removeInterface(aKey, xListener );
+ return m_aSpecialHelper.aLC.removeInterface(aKey, xListener );
else
return 0;
}
//-----------------------------------------------------------------------------
+ // relation function. Uses KeyToIndex
+/* template <class Key_, class KeyHash_, class KeyEq_, class KeyToIndex_>
+ SpecialListenerContainer<Key_,KeyHash_,KeyEq_, KeyToIndex_>::Index
+ SpecialListenerContainer<Key_,KeyHash_,KeyEq_, KeyToIndex_>::findIndexForKey(Key const& aKey)
+ {
+ m_aMapper.findIndexForKey(aKey);
+ }
+//-----------------------------------------------------------------------------
+ // relation function. Uses KeyToIndex
+ template <class Key_, class KeyHash_, class KeyEq_, class KeyToIndex_>
+ bool SpecialListenerContainer<Key_,KeyHash_,KeyEq_, KeyToIndex_>::findKeysForIndex(Index nIndex, KeyList & aKeys)
+ {
+ aKeys.clear();
+ m_aMapper.findKeysForIndex(nIndex,aKeys);
+ return !aKeys.empty();
+ }
+*///-----------------------------------------------------------------------------
+ // relation function. Uses KeyToIndex
+ template <class Key_, class KeyHash_, class KeyEq_, class KeyToIndex_>
+ void SpecialListenerContainer<Key_,KeyHash_,KeyEq_, KeyToIndex_>::implFillDisposer(DisposeNotifier& aNotifier, Index nIndex)
+ {
+ if (BasicContainerHelper* pMultiContainer = m_aContainers[nIndex].pContainer)
+ {
+ uno::Sequence< UnoType > aTypes(pMultiContainer->getContainedTypes());
+ for (sal_Int32 ix = 0; ix < aTypes.getLength(); ++ix)
+ {
+ ListenerContainer* pContainer = pMultiContainer->getContainer(aTypes[ix]);
+ OSL_ENSURE(pContainer,"No container, but the type ?");
+ if (pContainer)
+ aNotifier.appendAndClearContainer(pContainer);
+ }
+ }
+ KeyList aKeys;
+ if (m_aMapper.findKeysForIndex(nIndex,aKeys))
+ {
+ for(KeyList::iterator it = aKeys.begin(); it != aKeys.end(); ++it)
+ {
+ if (ListenerContainer* pContainer = m_aSpecialHelper.aLC.getContainer(*it))
+ {
+ aNotifier.appendAndClearContainer(pContainer);
+ }
+ }
+ }
+ }
+//-----------------------------------------------------------------------------
/////////////////////////////////////////////////////////////////////////////////////////////
diff --git a/configmgr/source/api2/makefile.mk b/configmgr/source/api2/makefile.mk
index 7988346a5294..5e9b011294fd 100644
--- a/configmgr/source/api2/makefile.mk
+++ b/configmgr/source/api2/makefile.mk
@@ -2,9 +2,9 @@
#
# $RCSfile: makefile.mk,v $
#
-# $Revision: 1.4 $
+# $Revision: 1.5 $
#
-# last change: $Author: dg $ $Date: 2000-11-13 12:14:15 $
+# last change: $Author: jb $ $Date: 2000-11-13 13:26:28 $
#
# The Contents of this file are made available subject to the terms of
# either of the following licenses
@@ -74,6 +74,7 @@ ENABLE_EXCEPTIONS=TRUE
# --- Files -------------------------------------
SLOFILES= \
+ $(SLO)$/listenercontainer.obj \
$(SLO)$/groupimpl.obj \
$(SLO)$/userimpl.obj \
$(SLO)$/provider.obj \
diff --git a/configmgr/source/api2/notifierimpl.hxx b/configmgr/source/api2/notifierimpl.hxx
index 9a1cb11908be..deda40317d69 100644
--- a/configmgr/source/api2/notifierimpl.hxx
+++ b/configmgr/source/api2/notifierimpl.hxx
@@ -2,9 +2,9 @@
*
* $RCSfile: notifierimpl.hxx,v $
*
- * $Revision: 1.2 $
+ * $Revision: 1.3 $
*
- * last change: $Author: jb $ $Date: 2000-11-10 12:22:55 $
+ * last change: $Author: jb $ $Date: 2000-11-13 13:26:28 $
*
* The Contents of this file are made available subject to the terms of
* either of the following licenses
@@ -93,6 +93,9 @@ namespace configmgr
mutable osl::Mutex m_aMutex;
public:
typedef configuration::NodeID Key;
+ typedef configuration::NodeID NodeID;
+ typedef configuration::NodeIDList NodeIDList;
+ typedef configuration::NodeOffset NodeOffset;
struct KeyHash
{
@@ -102,30 +105,44 @@ namespace configmgr
{
bool operator() (const Key& lhs,const Key& rhs) const {return lhs == rhs;}
};
- typedef MultiListenerContainer <Key,KeyHash,KeyEq> MultiContainer;
+ struct KeyToIndex
+ {
+ configuration::NodeID aRootNodeID;
+
+ KeyToIndex( configuration::Tree const& aTree ) : aRootNodeID(aTree,aTree.getRootNode()) {}
+ KeyToIndex( configuration::NodeID const& aID ) : aRootNodeID(aID) {}
+ bool findKeysForIndex(NodeOffset nNode, NodeIDList& aList)
+ {
+ aList.clear();
+ configuration::getAllChildrenHelper(configuration::findNodeFromIndex(aRootNodeID,nNode), aList);
+ return !aList.empty();
+ }
+ NodeOffset findIndexForKey(NodeID const& aNode)
+ {
+ return configuration::getParentHelper(aNode).toIndex();
+ }
+ };
+ typedef SpecialListenerContainer <Key,KeyHash,KeyEq,KeyToIndex> SpecialContainer;
public:
- MultiContainer m_aListeners;
+ SpecialContainer m_aListeners;
public:
/// construct this around the given Implementation, for the given tree
- NotifierImpl();
+ explicit
+ NotifierImpl(configuration::Tree const& aTree);
~NotifierImpl();
/// retrieve the mutex that is used by this
osl::Mutex& mutex() const { return m_aMutex; }
- /// dispose the given node, notifying listeners and sublisteners
- // (really bad style to put this here - should move to apinotifierimpl.cxx :-( )
- bool disposeNodeHelper(Key const& aNode, css::lang::EventObject const& aEvt) const;
-
/// Add a <type scope='com::sun::star::lang'>XEventListener</type> observing <var>aNode</var>.
void add(Key const& aNode, uno::Reference< css::lang::XEventListener > const& xListener)
{
OSL_PRECOND(xListener.is(), "ERROR: Unexpected NULL listener");
// ignore the names for now
- m_aListeners.addListener(aNode,xListener.get());
+ m_aListeners.addListener(aNode.toIndex(),getCppuType(&xListener),xListener.get());
}
/// Add a <type scope='com::sun::star::container'>XContainerListener</type> observing <var>aNode</var>.
@@ -134,7 +151,7 @@ namespace configmgr
OSL_PRECOND(xListener.is(), "ERROR: Unexpected NULL listener");
// ignore the names for now
- m_aListeners.addListener(aNode,xListener.get());
+ m_aListeners.addListener(aNode.toIndex(),getCppuType(&xListener),xListener.get());
}
/// Add a <type scope='com::sun::star::util'>XChangesListener</type> observing <var>aNode</var> and its descendants.
@@ -143,24 +160,40 @@ namespace configmgr
OSL_PRECOND(xListener.is(), "ERROR: Unexpected NULL listener");
// ignore the names for now
- m_aListeners.addListener(aNode,xListener.get());
+ m_aListeners.addListener(aNode.toIndex(),getCppuType(&xListener),xListener.get());
}
/// Add a <type scope='com::sun::star::beans'>XPropertyChangeListener</type> observing <var>aNode</var>.
- void add(Key const& aNode, uno::Reference< css::beans::XPropertyChangeListener > const& xListener)
+ void addNamed(Key const& aNode, uno::Reference< css::beans::XPropertyChangeListener > const& xListener)
+ {
+ OSL_PRECOND(xListener.is(), "ERROR: Unexpected NULL listener");
+
+ // ignore the names for now
+ m_aListeners.addSpecialListener(aNode,xListener.get());
+ }
+ /// Add a <type scope='com::sun::star::beans'>XPropertyChangeListener</type> observing <var>aNode</var>.
+ void addForAll(Key const& aNode, uno::Reference< css::beans::XPropertyChangeListener > const& xListener)
+ {
+ OSL_PRECOND(xListener.is(), "ERROR: Unexpected NULL listener");
+
+ // ignore the names for now
+ m_aListeners.addListener(aNode.toIndex(),getCppuType(&xListener),xListener.get());
+ }
+ /// Add a <type scope='com::sun::star::beans'>XVetoableChangeListener</type> constraining <var>aNode</var>.
+ void addNamed(Key const& aNode, uno::Reference< css::beans::XVetoableChangeListener > const& xListener)
{
OSL_PRECOND(xListener.is(), "ERROR: Unexpected NULL listener");
// ignore the names for now
- m_aListeners.addListener(aNode,xListener.get());
+ m_aListeners.addSpecialListener(aNode,xListener.get());
}
/// Add a <type scope='com::sun::star::beans'>XVetoableChangeListener</type> constraining <var>aNode</var>.
- void add(Key const& aNode, uno::Reference< css::beans::XVetoableChangeListener > const& xListener)
+ void addForAll(Key const& aNode, uno::Reference< css::beans::XVetoableChangeListener > const& xListener)
{
OSL_PRECOND(xListener.is(), "ERROR: Unexpected NULL listener");
// ignore the names for now
- m_aListeners.addListener(aNode,xListener.get());
+ m_aListeners.addListener(aNode.toIndex(),getCppuType(&xListener),xListener.get());
}
/** Add a <type scope='com::sun::star::beans'>XPropertiesChangeListener</type>
@@ -171,7 +204,7 @@ namespace configmgr
OSL_PRECOND(xListener.is(), "ERROR: Unexpected NULL listener");
// ignore the names for now
- m_aListeners.addListener(aNode,xListener.get());
+ m_aListeners.addListener(aNode.toIndex(),getCppuType(&xListener),xListener.get());
}
/** Add a <type scope='com::sun::star::beans'>XPropertiesChangeListener</type>
@@ -192,43 +225,56 @@ namespace configmgr
void remove(Key const& aNode, uno::Reference< css::lang::XEventListener > const& xListener)
{
// ignore the names for now
- m_aListeners.removeListener(aNode,xListener.get());
+ m_aListeners.removeListener(aNode.toIndex(),getCppuType(&xListener),xListener.get());
}
/// Remove a <type scope='com::sun::star::container'>XContainerListener</type> observing <var>aNode</var>.
void remove(Key const& aNode, uno::Reference< css::container::XContainerListener > const& xListener)
{
// ignore the names for now
- m_aListeners.removeListener(aNode,xListener.get());
+ m_aListeners.removeListener(aNode.toIndex(),getCppuType(&xListener),xListener.get());
}
/// Remove a <type scope='com::sun::star::util'>XChangesListener</type> observing <var>aNode</var> and its descendants.
void remove(Key const& aNode, uno::Reference< css::util::XChangesListener > const& xListener)
{
// ignore the names for now
- m_aListeners.removeListener(aNode,xListener.get());
+ m_aListeners.removeListener(aNode.toIndex(),getCppuType(&xListener),xListener.get());
}
/// Remove a <type scope='com::sun::star::beans'>XPropertyChangeListener</type> observing <var>aNode</var>.
- void remove(Key const& aNode, uno::Reference< css::beans::XPropertyChangeListener > const& xListener)
+ void removeNamed(Key const& aNode, uno::Reference< css::beans::XPropertyChangeListener > const& xListener)
+ {
+ // ignore the names for now
+ m_aListeners.removeSpecialListener(aNode,xListener.get());
+ }
+ /// Remove a <type scope='com::sun::star::beans'>XPropertyChangeListener</type> observing <var>aNode</var>.
+ void removeForAll(Key const& aNode, uno::Reference< css::beans::XPropertyChangeListener > const& xListener)
+ {
+ // ignore the names for now
+ m_aListeners.removeListener(aNode.toIndex(),getCppuType(&xListener),xListener.get());
+ }
+ /// Remove a <type scope='com::sun::star::beans'>XVetoableChangeListener</type> constraining <var>aNode</var>.
+ void removeNamed(Key const& aNode, uno::Reference< css::beans::XVetoableChangeListener > const& xListener)
{
// ignore the names for now
- m_aListeners.removeListener(aNode,xListener.get());
+ m_aListeners.removeSpecialListener(aNode,xListener.get());
}
/// Remove a <type scope='com::sun::star::beans'>XVetoableChangeListener</type> constraining <var>aNode</var>.
- void remove(Key const& aNode, uno::Reference< css::beans::XVetoableChangeListener > const& xListener)
+ void removeForAll(Key const& aNode, uno::Reference< css::beans::XVetoableChangeListener > const& xListener)
{
// ignore the names for now
- m_aListeners.removeListener(aNode,xListener.get());
+ m_aListeners.removeListener(aNode.toIndex(),getCppuType(&xListener),xListener.get());
}
+
/** Remove a <type scope='com::sun::star::beans'>XPropertiesChangeListener</type>
observing any properties of <var>aNode</var>.
*/
void remove(Key const& aNode, uno::Reference< css::beans::XPropertiesChangeListener > const& xListener)
{
// ignore the names for now
- m_aListeners.removeListener(aNode,xListener.get());
+ m_aListeners.removeListener(aNode.toIndex(),getCppuType(&xListener),xListener.get());
}
// ---------------------------------------------------------------------------------------------------
};
diff --git a/configmgr/source/inc/noderef.hxx b/configmgr/source/inc/noderef.hxx
index 4534950e7282..9a69b7a9be58 100644
--- a/configmgr/source/inc/noderef.hxx
+++ b/configmgr/source/inc/noderef.hxx
@@ -2,9 +2,9 @@
*
* $RCSfile: noderef.hxx,v $
*
- * $Revision: 1.2 $
+ * $Revision: 1.3 $
*
- * last change: $Author: jb $ $Date: 2000-11-10 12:19:02 $
+ * last change: $Author: jb $ $Date: 2000-11-13 13:26:30 $
*
* The Contents of this file are made available subject to the terms of
* either of the following licenses
@@ -208,6 +208,9 @@ namespace configmgr
/// checks, if this represents an real tree
bool isEmpty() const;
+ /// retrieves the number of immediately contained nodes
+ NodeOffset getContainedNodeCount() const;
+
/// checks whether the node <var>aNode</var> is a valid node in this tree.
bool isValidNode(NodeRef const& aNode) const;
@@ -318,6 +321,8 @@ namespace configmgr
friend bool operator < (NodeID const& lhs, NodeID const& rhs);
// hashing
size_t hashCode() const;
+ // use as index - returns a value in the range 0..rTree.getContainedNodes() for the tree used to construct this
+ NodeOffset toIndex() const;
private:
friend class TreeImplHelper;
TreeImpl* m_pTree;
@@ -420,6 +425,9 @@ namespace configmgr
void getAllContainedNodes(Tree const& aTree, NodeIDList& aList);
void getAllChildrenHelper(NodeID const& aNode, NodeIDList& aList);
+ NodeID getParentHelper(NodeID const& aNode);
+ NodeID findNeighbor(NodeID const& aNode, NodeOffset nIndex);
+ NodeID findNodeFromIndex(NodeID const& aNode, NodeOffset nIndex);
//-------------------------------------------------------------------------
diff --git a/configmgr/source/treemgr/noderef.cxx b/configmgr/source/treemgr/noderef.cxx
index 12676d82028a..3010f13a022f 100644
--- a/configmgr/source/treemgr/noderef.cxx
+++ b/configmgr/source/treemgr/noderef.cxx
@@ -2,9 +2,9 @@
*
* $RCSfile: noderef.cxx,v $
*
- * $Revision: 1.3 $
+ * $Revision: 1.4 $
*
- * last change: $Author: jb $ $Date: 2000-11-10 12:17:22 $
+ * last change: $Author: jb $ $Date: 2000-11-13 13:26:30 $
*
* The Contents of this file are made available subject to the terms of
* either of the following licenses
@@ -357,6 +357,14 @@ bool Tree::isEmpty() const
}
//-----------------------------------------------------------------------------
+NodeOffset Tree::getContainedNodeCount() const
+{
+ OSL_PRECOND(m_pImpl, "ERROR: Configuration: Counting nodes requires a valid Tree");
+
+ return m_pImpl ? m_pImpl->nodeCount() : 0;
+}
+//-----------------------------------------------------------------------------
+
bool Tree::isValidNode(NodeRef const& aNode) const
{
OSL_PRECOND(m_pImpl, "ERROR: Configuration: Tree operation requires a valid Tree");
@@ -671,6 +679,18 @@ size_t NodeID::hashCode() const
}
//-----------------------------------------------------------------------------
+NodeOffset NodeID::toIndex() const
+{
+ NodeOffset n = m_nNode;
+ if (m_pTree)
+ {
+ OSL_ENSURE(m_pTree->isValidNode(n),"Cannot produce valid Index for NodeID");
+
+ n -= m_pTree->root();
+ }
+ return n;
+}
+
//-----------------------------------------------------------------------------
// Free functions
//-----------------------------------------------------------------------------
@@ -832,6 +852,49 @@ void getAllChildrenHelper(NodeID const& aNode, NodeIDList& aList)
}
//-----------------------------------------------------------------------------
+NodeID getParentHelper(NodeID const& aNode)
+{
+ if (TreeImpl* pImpl = TreeImplHelper::tree(aNode))
+ {
+ if (NodeOffset const nNode = TreeImplHelper::offset(aNode))
+ {
+ if (NodeOffset nParent = pImpl->parent(nNode))
+ {
+ return NodeID(pImpl,nParent);
+ }
+ }
+ }
+ return NodeID(0,0);
+}
+//-----------------------------------------------------------------------------
+
+NodeID findNeighbor(NodeID const& aNode, NodeOffset nNeighbor)
+{
+ if (TreeImpl* pImpl = TreeImplHelper::tree(aNode))
+ {
+ if (pImpl->isValidNode(nNeighbor))
+ {
+ return NodeID(pImpl,nNeighbor);
+ }
+ }
+ return NodeID(0,0);
+}
+
+//-----------------------------------------------------------------------------
+NodeID findNodeFromIndex(NodeID const& aNode, NodeOffset nIndex)
+{
+ if (TreeImpl* pImpl = TreeImplHelper::tree(aNode))
+ {
+ NodeOffset nNode = nIndex + pImpl->root();
+ if (pImpl->isValidNode(nNode))
+ {
+ return NodeID(pImpl,nNode);
+ }
+ }
+ return NodeID(0,0);
+}
+
+//-----------------------------------------------------------------------------
bool isSimpleValue(Tree const& aTree, NodeRef const& aNode)
{
OSL_PRECOND( !aNode.isValid() || !aTree.isEmpty(), "ERROR: Configuration: Tree operation requires a valid Tree");