home *** CD-ROM | disk | FTP | other *** search
- /*******************************************************************************
- * FILE NAME: icolobsv.c *
- * *
- * DESCRIPTION: *
- * This file contains the implementation of classes/functions declared *
- * in icolobsv.hpp. *
- * *
- * COPYRIGHT: *
- * IBM Open Class Library *
- * (C) Copyright International Business Machines Corporation 1992, 1996 *
- * Licensed Material - Program-Property of IBM - All Rights Reserved. *
- * US Government Users Restricted Rights - Use, duplication, or disclosure *
- * restricted by GSA ADP Schedule Contract with IBM Corp. *
- * *
- *******************************************************************************/
-
- #include <icolobsv.hpp>
- #include <ipartccn.h>
- #include <ipartccl.h>
- #include <inotifev.hpp>
- #include <iostream.h>
-
-
- template <class Element, class ViewClass, class Collection>
- ICollectionObserver<Element, ViewClass, Collection>::
- ICollectionObserver ( )
- : fReportTo ( 0 ),
- fCollection ( 0 ),
- fElementObservers ( 0 ),
- fCursor ( fElementObservers )
- {
- }
-
- template <class Element, class ViewClass, class Collection>
- ICollectionObserver<Element, ViewClass, Collection>::
- ICollectionObserver( const ICollectionObserver<Element, ViewClass, Collection>& source )
- : fReportTo ( 0 ),
- fCollection ( 0 ),
- fElementObservers ( 0 ),
- fCursor ( fElementObservers )
- {
- setCollection( source.collection( ) );
- }
-
- template <class Element, class ViewClass, class Collection>
- ICollectionObserver<Element, ViewClass, Collection>::
- ~ICollectionObserver ( )
- {
-
- if ( fCollection )
- stopHandlingNotificationsFor( *fCollection );
-
- deleteAllElementObservers( );
- }
-
- template <class Element, class ViewClass, class Collection>
- void ICollectionObserver<Element,ViewClass,Collection>::
- deleteAllElementObservers( )
- {
- ElementObserver * elementObserver;
-
- while ( !fElementObservers.isEmpty( ) )
- {
- elementObserver = fElementObservers.firstElement( );
- elementObserver ->setElement ( 0 );
- fElementObservers.removeFirst( );
- delete elementObserver;
- }
- }
-
-
- template <class Element, class ViewClass, class Collection>
- ViewClass* ICollectionObserver<Element, ViewClass, Collection>::
- viewer ( ) const
- {
- return fReportTo;
- }
-
- template <class Element, class ViewClass, class Collection>
- ICollectionObserver<Element, ViewClass, Collection>&
- ICollectionObserver<Element, ViewClass, Collection>::
- setViewer( ViewClass* viewer )
- {
- fReportTo = viewer;
- return *this;
- }
-
- template <class Element, class ViewClass, class Collection>
- IPartOrderedCollection<Element>*
- ICollectionObserver<Element, ViewClass, Collection>::
- collection ( ) const
- {
- return fCollection;
- }
-
- template <class Element, class ViewClass, class Collection>
- ICollectionObserver<Element, ViewClass, Collection>&
- ICollectionObserver<Element, ViewClass, Collection>::
- setCollection( IPartOrderedCollection<Element>* collection )
- {
-
- if ( fCollection )
- {
- stopHandlingNotificationsFor( *fCollection );
-
- deleteAllElementObservers( );
- }
-
- fCollection = collection;
-
- if ( fCollection )
- {
- // initialize all connections to the ordered collection
- ICursor* cursor = fCollection->newCursor( );
- unsigned long index = 0;
- forCursor( *cursor )
- { //create connections
- fElementObservers.addAsLast(
- new ICollectionObserver<Element, ViewClass, Collection>::ElementObserver(
- fReportTo,
- fCollection->elementAt(*cursor),
- ++index ) );
- }
- handleNotificationsFor( *fCollection );
- delete cursor;
- }
-
- if ( fReportTo )
- {
- fReportTo->elementsChanged( ); // initialize all items
- fReportTo->collectionReplaced( ); // notify observers
- }
-
- return *this;
- }
-
-
- template <class Element, class ViewClass, class Collection>
- IObserver& ICollectionObserver<Element, ViewClass, Collection>::
- dispatchNotificationEvent( const INotificationEvent & anEvent )
- {
- INotificationId id( anEvent.notificationId());
- unsigned long data = anEvent.eventData().asUnsignedLong();
-
- if( ( id != IStandardNotifier::deleteId ) &&
- ( id != IWindow::deleteId ) )
- {
- #ifdef __WINDOWS__ // well, why not using fCollection ?????????????
- IAOrderedCollection <Element> collection (anEvent.notifier ());
- #endif
- IPartOrderedCollection<Element>* pCollection =
- #ifndef __WINDOWS__
- (IPartOrderedCollection<Element>*)&anEvent.notifier();
- #else
- &collection;
- #endif
-
- if ( id == IPartCollectionNotification::addedId )
- {
- IPartCollectionAddedEventData<Element>* pData =
- ((IPartCollectionAddedEventData<Element>*)
- ((char*)anEvent.eventData()));
- unsigned long index = pCollection->position( pData->cursor( ) );
- unsigned long count = fElementObservers.numberOfElements( );
- fElementObservers.addAtPosition(
- index,
- new ICollectionObserver<Element, ViewClass, Collection>::ElementObserver(
- fReportTo,
- pCollection->elementAt( pData->cursor()),
- index ) );
- if ( index <= count )
- {
- count = index; //save the index
- fElementObservers.setToPosition( index, fCursor );
- do
- {
- fElementObservers.elementAt( fCursor )->setPosition( index++ );
- } while ( fCursor.setToNext( ) );
- index = count; //restore the index
- }
-
- if ( fReportTo )
- fReportTo->elementAdded( index,
- pCollection->elementAt( pData->cursor( ) ) );
- }
- else if ( id == IPartCollectionNotification::removedId )
- {
- IPartCollectionRemovedEventData<Element>* pData =
- ((IPartCollectionRemovedEventData<Element>*)
- ((char*)anEvent.eventData()));
- ElementObserver * elementObserver;
- unsigned long index = pCollection->position( pData->cursor());
- unsigned long count = fElementObservers.numberOfElements();
- if ( index <= count )
- {
- fElementObservers.setToPosition( index, fCursor );
- elementObserver = fElementObservers.elementAt( fCursor );
- elementObserver ->setElement( 0 );
- fElementObservers.removeAtPosition( index );
- delete elementObserver;
- if ( index < count )
- {
- count = index; //save the deleted index
- fElementObservers.setToPosition( index, fCursor );
- do
- {
- fElementObservers.elementAt( fCursor )->setPosition( index++ );
- } while ( fCursor.setToNext( ) );
- index = count; //restore the deleted index
- }
-
- if ( fReportTo )
- fReportTo->elementDeleted( index );
- }
- }
- else if ( id == IPartCollectionNotification::replacedId )
- {
- IPartCollectionReplacedEventData<Element>* pData =
- ((IPartCollectionReplacedEventData<Element>*)
- ((char*)anEvent.eventData()));
- unsigned long index = pCollection->position( pData->cursor());
- fElementObservers.setToPosition( index, fCursor );
- fElementObservers.elementAt( fCursor )->setElement(
- pCollection->elementAt( pData->cursor() ) );
- if ( fReportTo )
- fReportTo->elementChanged( index,
- pCollection->elementAt( pData->cursor()));
- }
- else if ( id == IPartCollectionNotification::modifiedId )
- {
- unsigned long collectionCount = pCollection->numberOfElements ( );
- unsigned long observerCount = fElementObservers.numberOfElements( );
- ElementObserver * elementObserver;
- if ( collectionCount < observerCount )
- {
- if ( collectionCount )
- {
- unsigned long drop = fElementObservers.numberOfElements() -
- collectionCount;
- while ( drop )
- {
- fElementObservers.setToPosition( collectionCount + drop, fCursor );
- elementObserver = fElementObservers.elementAt( fCursor );
- elementObserver ->setElement( 0 );
- fElementObservers.removeAtPosition( collectionCount + drop );
- delete elementObserver;
- drop--;
- }
- }
- else
- {
- deleteAllElementObservers( );
- }
- }
- else if ( collectionCount > observerCount )
- {
- unsigned long index = observerCount + 1;
- ICursor* cursor = fCollection->newCursor( );
- fCollection->setToPosition( index, *cursor );
- while ( cursor->isValid( ) )
- {
- fElementObservers.addAsLast(
- new ICollectionObserver<Element, ViewClass, Collection>::ElementObserver(
- fReportTo,
- pCollection->elementAt( *cursor ),
- index++ ) );
- cursor->setToNext( );
- }
- delete cursor;
- }
-
- ICursor* aCursor = fCollection->newCursor();
- for( aCursor->setToFirst(), fCursor.setToFirst();
- aCursor->isValid() && fCursor.isValid();
- aCursor->setToNext(), fCursor.setToNext() )
- {
- fElementObservers.elementAt( fCursor )->setElement(
- fCollection->elementAt( *aCursor ));
- }
- delete aCursor;
-
- if ( fReportTo )
- fReportTo->elementsChanged( );
- }
- }
- else if ( ( id == IStandardNotifier::deleteId ) ||
- ( id == IWindow::deleteId ) )
- {
- fCollection = 0;
- deleteAllElementObservers( );
-
- if ( fReportTo )
- {
- fReportTo->elementsChanged ( ); // tell view no items
- fReportTo->collectionReplaced( ); // notify observers
- }
- }
-
- return *this;
- }
-
- template <class Element, class ViewClass, class Collection>
- ICollectionObserver<Element, ViewClass, Collection>::ElementObserver::
- ElementObserver( ViewClass* viewer,
- Element element,
- unsigned long position )
- : fInterestedParty ( viewer ),
- fElement ( element ),
- fPosition ( position ) // element positions begin at 1
- {
- if ( fElement ) // TB
- handleNotificationsFor( *fElement );
- }
-
- template <class Element, class ViewClass, class Collection>
- ICollectionObserver<Element, ViewClass, Collection>::ElementObserver::
- ElementObserver(
- const ICollectionObserver<Element, ViewClass, Collection>::ElementObserver & rhs )
- : fInterestedParty ( rhs.fInterestedParty ),
- fElement ( rhs.fElement ),
- fPosition ( rhs.fPosition ) // element positions begin at 1
- {
- if ( fElement ) // TB
- handleNotificationsFor( *fElement );
- }
-
- template <class Element, class ViewClass, class Collection>
- ICollectionObserver<Element, ViewClass, Collection>::ElementObserver::
- ~ElementObserver ( )
- {
- if ( fElement )
- {
- stopHandlingNotificationsFor( *fElement );
- }
- }
-
- template <class Element, class ViewClass, class Collection>
- IObserver& ICollectionObserver<Element, ViewClass, Collection>::ElementObserver::
- dispatchNotificationEvent( const INotificationEvent & anEvent )
- {
- INotificationId id( anEvent.notificationId() );
-
- if ( anEvent.hasNotifierAttrChanged() )
- {
- if ( !( ( id == IStandardNotifier::deleteId ) ||
- ( id == IWindow::deleteId ) ) )
- {
- if ( fInterestedParty )
- fInterestedParty->elementChanged( fPosition, fElement );
- }
- else
- {
- fElement = 0;
- fInterestedParty = 0;
- }
- }
-
- return *this;
- }
-
- template <class Element, class ViewClass, class Collection>
- Element ICollectionObserver<Element, ViewClass, Collection>::ElementObserver::
- element ( ) const
- {
- return fElement;
- }
-
- template <class Element, class ViewClass, class Collection>
- ICollectionObserver<Element, ViewClass, Collection>::ElementObserver&
- ICollectionObserver<Element, ViewClass, Collection>::ElementObserver::
- setElement( const Element element )
- {
- if ( fElement )
- {
- stopHandlingNotificationsFor( *fElement );
- }
-
- fElement = element;
-
- if ( fElement )
- {
- handleNotificationsFor( *fElement );
- }
- return *this;
- }
-
- template <class Element, class ViewClass, class Collection>
- unsigned long ICollectionObserver<Element, ViewClass, Collection>::ElementObserver::
- position ( ) const
- {
- return fPosition;
- }
-
- template <class Element, class ViewClass, class Collection>
- ICollectionObserver<Element, ViewClass, Collection>::ElementObserver &
- ICollectionObserver<Element, ViewClass, Collection>::ElementObserver::
- setPosition( unsigned long position )
- {
- fPosition = position;
- return *this;
- }
-
- template <class Element, class ViewClass, class Collection>
- ICollectionObserver<Element, ViewClass, Collection>::ElementObserver&
- ICollectionObserver<Element, ViewClass, Collection>::ElementObserver::
- operator= ( const ElementObserver& rhs )
- {
- fElement = rhs.fElement;
- fPosition = rhs.fPosition;
- return *this;
- }
-
-