home *** CD-ROM | disk | FTP | other *** search
/ Power GUI Programming with VisualAge C++ / powergui.iso / trialva / ibmcppw / include / icolobsv.c < prev    next >
Encoding:
C/C++ Source or Header  |  1996-02-22  |  13.7 KB  |  413 lines

  1. /*******************************************************************************
  2. * FILE NAME: icolobsv.c                                                        *
  3. *                                                                              *
  4. * DESCRIPTION:                                                                 *
  5. *   This file contains the implementation of classes/functions declared        *
  6. *   in icolobsv.hpp.                                                           *
  7. *                                                                              *
  8. * COPYRIGHT:                                                                   *
  9. *   IBM Open Class Library                                                     *
  10. *   (C) Copyright International Business Machines Corporation 1992, 1996       *
  11. *   Licensed Material - Program-Property of IBM - All Rights Reserved.         *
  12. *   US Government Users Restricted Rights - Use, duplication, or disclosure    *
  13. *   restricted by GSA ADP Schedule Contract with IBM Corp.                     *
  14. *                                                                              *
  15. *******************************************************************************/
  16.  
  17. #include <icolobsv.hpp>
  18. #include <ipartccn.h>
  19. #include <ipartccl.h>
  20. #include <inotifev.hpp>
  21. #include <iostream.h>
  22.  
  23.  
  24. template <class Element, class ViewClass, class Collection>
  25.   ICollectionObserver<Element, ViewClass, Collection>::
  26.     ICollectionObserver ( )
  27.     : fReportTo         ( 0 ),
  28.       fCollection       ( 0 ),
  29.       fElementObservers ( 0 ),
  30.       fCursor           ( fElementObservers )
  31. {
  32. }
  33.  
  34. template <class Element, class ViewClass, class Collection>
  35.   ICollectionObserver<Element, ViewClass, Collection>::
  36.     ICollectionObserver( const ICollectionObserver<Element, ViewClass, Collection>& source  )
  37.     : fReportTo         ( 0 ),
  38.       fCollection       ( 0 ),
  39.       fElementObservers ( 0 ),
  40.       fCursor           ( fElementObservers )
  41. {
  42.   setCollection( source.collection( ) );
  43. }
  44.  
  45. template <class Element, class ViewClass, class Collection>
  46.   ICollectionObserver<Element, ViewClass, Collection>::
  47.    ~ICollectionObserver ( )
  48. {
  49.  
  50.   if ( fCollection )
  51.     stopHandlingNotificationsFor( *fCollection );
  52.  
  53.   deleteAllElementObservers( );
  54. }
  55.  
  56. template <class Element, class ViewClass, class Collection>
  57.   void ICollectionObserver<Element,ViewClass,Collection>::
  58.     deleteAllElementObservers( )
  59. {
  60.   ElementObserver * elementObserver;
  61.  
  62.   while ( !fElementObservers.isEmpty( ) )
  63.   {
  64.     elementObserver = fElementObservers.firstElement( );
  65.     elementObserver ->setElement ( 0 );
  66.     fElementObservers.removeFirst( );
  67.     delete elementObserver;
  68.   }
  69. }
  70.  
  71.  
  72. template <class Element, class ViewClass, class Collection>
  73.   ViewClass* ICollectionObserver<Element, ViewClass, Collection>::
  74.     viewer ( ) const
  75. {
  76.   return fReportTo;
  77. }
  78.  
  79. template <class Element, class ViewClass, class Collection>
  80.   ICollectionObserver<Element, ViewClass, Collection>&
  81.     ICollectionObserver<Element, ViewClass, Collection>::
  82.       setViewer( ViewClass* viewer )
  83. {
  84.   fReportTo = viewer;
  85.   return *this;
  86. }
  87.  
  88. template <class Element, class ViewClass, class Collection>
  89.   IPartOrderedCollection<Element>*
  90.     ICollectionObserver<Element, ViewClass, Collection>::
  91.       collection ( ) const
  92. {
  93.   return fCollection;
  94. }
  95.  
  96. template <class Element, class ViewClass, class Collection>
  97.   ICollectionObserver<Element, ViewClass, Collection>&
  98.     ICollectionObserver<Element, ViewClass, Collection>::
  99.       setCollection( IPartOrderedCollection<Element>* collection )
  100. {
  101.  
  102.   if ( fCollection )
  103.   {
  104.     stopHandlingNotificationsFor( *fCollection );
  105.  
  106.     deleteAllElementObservers( );
  107.   }
  108.  
  109.   fCollection = collection;
  110.  
  111.   if ( fCollection )
  112.   {
  113.     // initialize all connections to the ordered collection
  114.     ICursor*      cursor = fCollection->newCursor( );
  115.     unsigned long  index = 0;
  116.     forCursor( *cursor )
  117.     {                  //create connections
  118.       fElementObservers.addAsLast(
  119.          new ICollectionObserver<Element, ViewClass, Collection>::ElementObserver(
  120.             fReportTo,
  121.             fCollection->elementAt(*cursor),
  122.             ++index ) );
  123.     }
  124.     handleNotificationsFor( *fCollection );
  125.     delete cursor;
  126.   }
  127.  
  128.   if ( fReportTo )
  129.   {
  130.     fReportTo->elementsChanged( );    // initialize all items
  131.     fReportTo->collectionReplaced( ); // notify observers
  132.   }
  133.  
  134.   return *this;
  135. }
  136.  
  137.  
  138. template <class Element, class ViewClass, class Collection>
  139.   IObserver&   ICollectionObserver<Element, ViewClass, Collection>::
  140.     dispatchNotificationEvent( const INotificationEvent & anEvent )
  141. {
  142.   INotificationId     id( anEvent.notificationId());
  143.   unsigned long       data = anEvent.eventData().asUnsignedLong();
  144.  
  145.   if( ( id != IStandardNotifier::deleteId ) &&
  146.       ( id != IWindow::deleteId           )    )
  147.   {
  148.   #ifdef __WINDOWS__ // well, why not using fCollection ?????????????
  149.     IAOrderedCollection <Element> collection (anEvent.notifier ());
  150.   #endif
  151.     IPartOrderedCollection<Element>*    pCollection =
  152.   #ifndef __WINDOWS__
  153.                      (IPartOrderedCollection<Element>*)&anEvent.notifier();
  154.   #else
  155.                      &collection;
  156.   #endif
  157.  
  158.     if ( id == IPartCollectionNotification::addedId )
  159.     {
  160.       IPartCollectionAddedEventData<Element>*    pData =
  161.           ((IPartCollectionAddedEventData<Element>*)
  162.               ((char*)anEvent.eventData()));
  163.       unsigned long index = pCollection->position( pData->cursor( ) );
  164.       unsigned long count = fElementObservers.numberOfElements( );
  165.       fElementObservers.addAtPosition(
  166.          index,
  167.          new ICollectionObserver<Element, ViewClass, Collection>::ElementObserver(
  168.              fReportTo,
  169.              pCollection->elementAt( pData->cursor()),
  170.              index ) );
  171.       if ( index <= count )
  172.       {
  173.         count = index;     //save the index
  174.         fElementObservers.setToPosition( index, fCursor );
  175.         do
  176.         {
  177.           fElementObservers.elementAt( fCursor )->setPosition( index++ );
  178.         } while ( fCursor.setToNext( ) );
  179.         index = count;     //restore the index
  180.       }
  181.  
  182.       if ( fReportTo )
  183.         fReportTo->elementAdded( index,
  184.                                  pCollection->elementAt( pData->cursor( ) ) );
  185.     }
  186.     else if ( id == IPartCollectionNotification::removedId )
  187.     {
  188.       IPartCollectionRemovedEventData<Element>*    pData =
  189.          ((IPartCollectionRemovedEventData<Element>*)
  190.              ((char*)anEvent.eventData()));
  191.       ElementObserver * elementObserver;
  192.       unsigned long index = pCollection->position( pData->cursor());
  193.       unsigned long count = fElementObservers.numberOfElements();
  194.       if ( index <= count )
  195.       {
  196.         fElementObservers.setToPosition( index, fCursor );
  197.         elementObserver = fElementObservers.elementAt( fCursor );
  198.         elementObserver ->setElement( 0 );
  199.         fElementObservers.removeAtPosition( index );
  200.         delete elementObserver;
  201.         if ( index < count )
  202.         {
  203.           count = index;     //save the deleted index
  204.           fElementObservers.setToPosition( index, fCursor );
  205.           do
  206.           {
  207.             fElementObservers.elementAt( fCursor )->setPosition( index++ );
  208.           } while ( fCursor.setToNext( ) );
  209.           index = count;     //restore the deleted index
  210.         }
  211.  
  212.         if ( fReportTo )
  213.           fReportTo->elementDeleted( index );
  214.       }
  215.     }
  216.     else if ( id == IPartCollectionNotification::replacedId )
  217.     {
  218.       IPartCollectionReplacedEventData<Element>*    pData =
  219.          ((IPartCollectionReplacedEventData<Element>*)
  220.              ((char*)anEvent.eventData()));
  221.       unsigned long index = pCollection->position( pData->cursor());
  222.       fElementObservers.setToPosition( index, fCursor );
  223.       fElementObservers.elementAt( fCursor )->setElement(
  224.                   pCollection->elementAt( pData->cursor() ) );
  225.       if ( fReportTo )
  226.         fReportTo->elementChanged( index,
  227.                                    pCollection->elementAt( pData->cursor()));
  228.     }
  229.     else if ( id == IPartCollectionNotification::modifiedId )
  230.     {
  231.       unsigned long collectionCount = pCollection->numberOfElements     ( );
  232.       unsigned long observerCount   = fElementObservers.numberOfElements( );
  233.       ElementObserver * elementObserver;
  234.       if ( collectionCount < observerCount )
  235.       {
  236.         if ( collectionCount )
  237.         {
  238.           unsigned long drop = fElementObservers.numberOfElements() -
  239.                                  collectionCount;
  240.           while ( drop )
  241.           {
  242.             fElementObservers.setToPosition( collectionCount + drop, fCursor );
  243.             elementObserver = fElementObservers.elementAt( fCursor );
  244.             elementObserver ->setElement( 0 );
  245.             fElementObservers.removeAtPosition( collectionCount + drop );
  246.             delete elementObserver;
  247.             drop--;
  248.           }
  249.         }
  250.         else
  251.         {
  252.           deleteAllElementObservers( );
  253.         }
  254.       }
  255.       else if ( collectionCount > observerCount )
  256.       {
  257.         unsigned long index = observerCount + 1;
  258.         ICursor*  cursor    = fCollection->newCursor( );
  259.         fCollection->setToPosition( index, *cursor );
  260.         while ( cursor->isValid( ) )
  261.         {
  262.           fElementObservers.addAsLast(
  263.              new ICollectionObserver<Element, ViewClass, Collection>::ElementObserver(
  264.                 fReportTo,
  265.                 pCollection->elementAt( *cursor ),
  266.                 index++ ) );
  267.           cursor->setToNext( );
  268.         }
  269.         delete cursor;
  270.       }
  271.  
  272.       ICursor*  aCursor = fCollection->newCursor();
  273.       for( aCursor->setToFirst(), fCursor.setToFirst();
  274.            aCursor->isValid()  && fCursor.isValid();
  275.            aCursor->setToNext(),  fCursor.setToNext() )
  276.       {
  277.         fElementObservers.elementAt( fCursor )->setElement(
  278.                fCollection->elementAt( *aCursor ));
  279.       }
  280.       delete aCursor;
  281.  
  282.       if ( fReportTo )
  283.         fReportTo->elementsChanged( );
  284.     }
  285.   }
  286.   else if ( ( id == IStandardNotifier::deleteId ) ||
  287.             ( id == IWindow::deleteId           )    )
  288.   {
  289.     fCollection = 0;
  290.     deleteAllElementObservers( );
  291.  
  292.     if ( fReportTo )
  293.     {
  294.       fReportTo->elementsChanged   ( ); // tell view no items
  295.       fReportTo->collectionReplaced( ); // notify observers
  296.     }
  297.   }
  298.  
  299.   return *this;
  300. }
  301.  
  302. template <class Element, class ViewClass, class Collection>
  303.   ICollectionObserver<Element, ViewClass, Collection>::ElementObserver::
  304.     ElementObserver( ViewClass*     viewer,
  305.                      Element        element,
  306.                      unsigned long  position )
  307.     : fInterestedParty ( viewer ),
  308.       fElement         ( element ),
  309.       fPosition        ( position )           // element positions begin at 1
  310. {
  311.   if ( fElement ) // TB
  312.     handleNotificationsFor( *fElement );
  313. }
  314.  
  315. template <class Element, class ViewClass, class Collection>
  316.   ICollectionObserver<Element, ViewClass, Collection>::ElementObserver::
  317.     ElementObserver(
  318.        const ICollectionObserver<Element, ViewClass, Collection>::ElementObserver & rhs )
  319.     : fInterestedParty ( rhs.fInterestedParty ),
  320.       fElement         ( rhs.fElement ),
  321.       fPosition        ( rhs.fPosition )    // element positions begin at 1
  322. {
  323.   if ( fElement ) // TB
  324.     handleNotificationsFor( *fElement );
  325. }
  326.  
  327. template <class Element, class ViewClass, class Collection>
  328.   ICollectionObserver<Element, ViewClass, Collection>::ElementObserver::
  329.    ~ElementObserver ( )
  330. {
  331.   if ( fElement )
  332.   {
  333.     stopHandlingNotificationsFor( *fElement );
  334.   }
  335. }
  336.  
  337. template <class Element, class ViewClass, class Collection>
  338.   IObserver&  ICollectionObserver<Element, ViewClass, Collection>::ElementObserver::
  339.     dispatchNotificationEvent( const INotificationEvent & anEvent )
  340. {
  341.   INotificationId     id( anEvent.notificationId() );
  342.  
  343.   if ( anEvent.hasNotifierAttrChanged() )
  344.   {
  345.     if ( !( ( id == IStandardNotifier::deleteId ) ||
  346.             ( id == IWindow::deleteId ) ) )
  347.     {
  348.       if ( fInterestedParty )
  349.         fInterestedParty->elementChanged( fPosition, fElement );
  350.     }
  351.     else
  352.     {
  353.       fElement         = 0;
  354.       fInterestedParty = 0;
  355.     }
  356.   }
  357.  
  358.   return *this;
  359. }
  360.  
  361. template <class Element, class ViewClass, class Collection>
  362.   Element  ICollectionObserver<Element, ViewClass, Collection>::ElementObserver::
  363.     element ( ) const
  364. {
  365.   return fElement;
  366. }
  367.  
  368. template <class Element, class ViewClass, class Collection>
  369.   ICollectionObserver<Element, ViewClass, Collection>::ElementObserver&
  370.     ICollectionObserver<Element, ViewClass, Collection>::ElementObserver::
  371.       setElement( const Element element )
  372. {
  373.   if ( fElement )
  374.   {
  375.     stopHandlingNotificationsFor( *fElement );
  376.   }
  377.  
  378.   fElement    = element;
  379.  
  380.   if ( fElement )
  381.   {
  382.     handleNotificationsFor( *fElement );
  383.   }
  384.   return *this;
  385. }
  386.  
  387. template <class Element, class ViewClass, class Collection>
  388.   unsigned long  ICollectionObserver<Element, ViewClass, Collection>::ElementObserver::
  389.     position ( ) const
  390. {
  391.   return fPosition;
  392. }
  393.  
  394. template <class Element, class ViewClass, class Collection>
  395.   ICollectionObserver<Element, ViewClass, Collection>::ElementObserver  &
  396.     ICollectionObserver<Element, ViewClass, Collection>::ElementObserver::
  397.       setPosition( unsigned long  position )
  398. {
  399.   fPosition = position;
  400.   return *this;
  401. }
  402.  
  403. template <class Element, class ViewClass, class Collection>
  404.   ICollectionObserver<Element, ViewClass, Collection>::ElementObserver&
  405.     ICollectionObserver<Element, ViewClass, Collection>::ElementObserver::
  406.       operator= ( const ElementObserver& rhs )
  407. {
  408.   fElement  = rhs.fElement;
  409.   fPosition = rhs.fPosition;
  410.   return *this;
  411. }
  412.  
  413.