diff options
author | Jörg Barfurth <jb@openoffice.org> | 2000-11-13 12:27:15 +0000 |
---|---|---|
committer | Jörg Barfurth <jb@openoffice.org> | 2000-11-13 12:27:15 +0000 |
commit | 7ebe4146b2fef84d1c2e3fbc542c1919ccd0eb7b (patch) | |
tree | 63dbdfa289c9b5598e913d5250169679aa377af2 | |
parent | ecdcb9d2a60874c8d05f8ea22cc56c7b4d698466 (diff) |
Revised storage of notifiers
-rw-r--r-- | configmgr/source/api2/apinotifierimpl.cxx | 81 | ||||
-rw-r--r-- | configmgr/source/api2/apitreeimplobj.cxx | 14 | ||||
-rw-r--r-- | configmgr/source/api2/confignotifier.cxx | 55 | ||||
-rw-r--r-- | configmgr/source/api2/confignotifier.hxx | 26 | ||||
-rw-r--r-- | configmgr/source/api2/listenercontainer.cxx | 114 | ||||
-rw-r--r-- | configmgr/source/api2/listenercontainer.hxx | 397 | ||||
-rw-r--r-- | configmgr/source/api2/makefile.mk | 5 | ||||
-rw-r--r-- | configmgr/source/api2/notifierimpl.hxx | 96 | ||||
-rw-r--r-- | configmgr/source/inc/noderef.hxx | 12 | ||||
-rw-r--r-- | configmgr/source/treemgr/noderef.cxx | 67 |
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"); |