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

  1. /*******************************************************************************
  2. * FILE NAME: ivbcnr.c                                                          *
  3. *                                                                              *
  4. * DESCRIPTION:                                                                 *
  5. *   This file contains the implementation of classes/functions declared        *
  6. *   in ivbcnr.h.                                                               *
  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. #include  <ivbcnr.h>
  17. #include  <icolvwd.hpp>
  18. #include  <iseq.h>
  19. #include  <ivseq.h>
  20. #include  <ipartccl.h>
  21. #include  <istring.hpp>
  22. #include  <iexcept.hpp>
  23. #include  <icconst.h>
  24. #include  <inotifev.hpp>
  25. #include  <imoushdr.hpp>
  26. #include  <ipoint.hpp>
  27.  
  28.  
  29. template <class ViewClass>
  30.   class IVBContainerMouseHandler : public IMouseHandler {
  31.  
  32. public:
  33.   IVBContainerMouseHandler(ViewClass* aVBContainer)
  34.   {
  35.     pVBContainer = aVBContainer;
  36.     handleEventsFor(pVBContainer);
  37.   }
  38.  
  39. virtual
  40.   ~IVBContainerMouseHandler()
  41.   {
  42.     stopHandlingEventsFor(pVBContainer);
  43.   }
  44.  
  45. protected:
  46.   virtual Boolean mouseClicked(IMouseClickEvent& mouseEvent)
  47.   {
  48.     if ( (mouseEvent.mouseButton() == IMouseClickEvent::button2) &&
  49.          (mouseEvent.mouseAction() == IMouseClickEvent::down) )
  50.     {
  51.  
  52.       //Save the point away in the IVBContainerControl.
  53.       pVBContainer->setButton2Point(
  54.          IWindow::mapPoint(
  55.             IWindow::pointerPosition(),   /* mouse pos in desktop coords */
  56.             IWindow::desktopWindow()->handle(),           /* from window */
  57.             pVBContainer->handle())                       /* to window   */
  58.          );
  59.     }
  60.     return false;
  61.   }
  62.  
  63. private:
  64.   ViewClass * pVBContainer;
  65.  
  66. }; //IVBContainerMouseHandler
  67.  
  68. template <class Element, class ViewClass, class Collection>
  69.   class IVBContainerControlData : public IBase {
  70.  
  71. public:
  72.  
  73.   IVBContainerControlData ( );
  74.  
  75.  ~IVBContainerControlData ( );
  76.  
  77.  ICollectionViewData< Element,
  78.                      ViewClass,
  79.                      Collection >
  80.    *fCollectionViewData;
  81.  IVSequence<Element> * pSelectedElements;
  82.  IVSequence<Element> * pButton2Elements;
  83.  IVSequence<IContainerObject *> * pSelectedCnrObjects;
  84.  IVSequence<IContainerObject *> * pButton2CnrObjects;
  85.  IVSequence<unsigned long> * pSelectedCollectionPositions;
  86.  IVSequence<unsigned long> * pButton2CollectionPositions;
  87.  IVBContainerMouseHandler< ViewClass > *pMouseHandler;
  88.  IPoint fButton2Point;
  89.  
  90. private:
  91. /*------------------------- Hidden Members -----------------------------------*/
  92.   IVBContainerControlData
  93.              ( const IVBContainerControlData< Element, ViewClass, Collection >& source );
  94. IVBContainerControlData<Element,ViewClass, Collection>
  95.  &operator=  ( const IVBContainerControlData< Element, ViewClass, Collection >& source );
  96.  
  97.  
  98. };
  99.  
  100. template <class Element, class ViewClass, class Collection>
  101.   IVBContainerControlData<Element, ViewClass, Collection>::
  102.     IVBContainerControlData( )
  103. {
  104.   fCollectionViewData = new
  105.         ICollectionViewData< Element,
  106.                              ViewClass,
  107.                              Collection > ( ) ;
  108. }
  109.  
  110. template <class Element, class ViewClass, class Collection>
  111.   IVBContainerControlData<Element,ViewClass,Collection>::
  112.    ~IVBContainerControlData ( )
  113. {
  114.   delete pMouseHandler;
  115.   delete pButton2CnrObjects;
  116.   delete pSelectedCnrObjects;
  117.   delete pButton2Elements;
  118.   delete pSelectedElements;
  119.   delete fCollectionViewData;
  120. }
  121.  
  122. template <class Element, class Collection, class CnrElement>
  123.   IVBContainerControl<Element,Collection,CnrElement>::
  124.     IVBContainerControl ( unsigned long                       identifier,
  125.                           IWindow*                            parent,
  126.                           IWindow*                            owner ,
  127.                           const IRectangle&                   initial,
  128.                           const IContainerControl::Style&     style,
  129.                           const IContainerControl::Attribute& attribute )
  130.     : IContainerControl( identifier, parent, owner, initial, style, attribute )
  131. {
  132.   initialize( );
  133. }
  134.  
  135.  
  136. template <class Element, class Collection, class CnrElement>
  137.   IVBContainerControl<Element,Collection,CnrElement>::
  138.     IVBContainerControl ( unsigned long   identifier,
  139.                           IWindow*        parent   )
  140.     : IContainerControl( identifier, parent )
  141. {
  142.   initialize( );
  143. }
  144.  
  145. template <class Element, class Collection, class CnrElement>
  146.   IVBContainerControl<Element,Collection,CnrElement>::
  147.     IVBContainerControl( const IWindowHandle&  handle  )
  148.     : IContainerControl( handle )
  149. {
  150.   initialize( );
  151. }
  152.  
  153. template <class Element, class Collection, class CnrElement>
  154.   IVBContainerControl<Element,Collection,CnrElement>::
  155.    ~IVBContainerControl ( )
  156. {
  157.   disableNotification();
  158.  
  159.   delete fVBContainerControlData;
  160. }
  161.  
  162. template <class Element, class Collection, class CnrElement>
  163.   INotificationId const IVBContainerControl<Element,Collection,CnrElement>::button2PointId =
  164.     "IVBContainerControl::button2PointId";
  165. template <class Element, class Collection, class CnrElement>
  166.   INotificationId const IVBContainerControl<Element,Collection,CnrElement>::itemChangedId =
  167.     "IVBContainerControl::itemChangedId";
  168. template <class Element, class Collection, class CnrElement>
  169.   INotificationId const IVBContainerControl<Element,Collection,CnrElement>::itemsId =
  170.     "IVBContainerControl::itemsId";
  171.  
  172. template <class Element, class Collection, class CnrElement>
  173.   Collection*  IVBContainerControl<Element,Collection,CnrElement>:: items( ) const
  174. {
  175.   return  (Collection *)fVBContainerControlData->fCollectionViewData->fCollectionObserver.collection();
  176. }
  177.  
  178. template <class Element, class Collection, class CnrElement>
  179.   IVBContainerControl<Element,Collection,CnrElement>&   IVBContainerControl<Element,Collection,CnrElement>::
  180.     setItems( Collection* collection )
  181. {
  182.   fVBContainerControlData->fCollectionViewData->fCollectionObserver.setCollection( collection );
  183.  
  184.   return *this;
  185. }
  186.  
  187. template <class Element, class Collection, class CnrElement>
  188.   IVBContainerControl<Element,Collection,CnrElement>&
  189.     IVBContainerControl<Element,Collection,CnrElement> :: elementsChanged ( )
  190. {
  191.   ICursor*       pCursor;
  192.   Collection*    collection;
  193.   collection   = items( );
  194.  
  195.   /*  Clear container and repopulate w/ current representations */
  196.   Boolean refreshOn = isRefreshOn();
  197.   setRefreshOff    ( );
  198.   deleteAllObjects ( );
  199.  
  200.   if ( collection )
  201.   {
  202.     pCursor         = collection->newCursor( );
  203.     forCursor( *pCursor )
  204.     {
  205.       addObject( new CnrElement( *( collection->elementAt( *pCursor ) ) ) );
  206.     }
  207.     delete pCursor;
  208.   }
  209.  
  210.   setRefreshOn ( );
  211.   refresh      ( );
  212.   setRefreshOn ( refreshOn );
  213.  
  214.   return *this;
  215. }
  216.  
  217.  
  218. template <class Element, class Collection, class CnrElement>
  219.   IVBContainerControl<Element,Collection,CnrElement>&
  220.     IVBContainerControl<Element,Collection,CnrElement>::
  221.       elementAdded ( unsigned long position, const Element&  element )
  222. {
  223.   IContainerObject* cnrObject;
  224.   Collection*       collection;
  225.   Boolean           refreshOn = isRefreshOn( );
  226.   setRefreshOff    ( );
  227.  
  228.   collection      = items( );
  229.  
  230.   if ( position == IVBContainerControl<Element,Collection,CnrElement>::firstItem )
  231.     cnrObject = 0;
  232.   else
  233.     cnrObject = objectAt(position - 2);
  234.  
  235.   addObjectAfter( new CnrElement( *(collection->elementAtPosition( position )) ),
  236.                   cnrObject );
  237.  
  238.   if (refreshOn)
  239.   {
  240.     setRefreshOn( );
  241.     refresh     ( );
  242.   }
  243.  
  244.   return *this;
  245. }
  246.  
  247. template <class Element, class Collection, class CnrElement>
  248.   IVBContainerControl<Element,Collection,CnrElement>&
  249.     IVBContainerControl<Element,Collection,CnrElement>::
  250.       elementDeleted ( unsigned long position )
  251. {
  252.  
  253.   Boolean refreshOn = isRefreshOn( );
  254.   setRefreshOff( );
  255.   delete  objectAt( position - 1 );
  256.   if (refreshOn)
  257.   {
  258.     setRefreshOn( );
  259.     refresh     ( );
  260.   }
  261.   return *this;
  262. }
  263.  
  264.  
  265. template <class Element, class Collection, class CnrElement>
  266.   IVBContainerControl<Element,Collection,CnrElement>&
  267.     IVBContainerControl<Element,Collection,CnrElement>::
  268.       elementChanged ( unsigned long  position, const Element&  element )
  269. {
  270.   IVBContainerObject* cnrObject;
  271.   Boolean           selected;
  272.   Boolean           cursored;
  273.   Boolean           refreshOn = isRefreshOn( );
  274.  
  275.   setRefreshOff   ();
  276.   cnrObject = ((IVBContainerObject * )objectAt  ( position - 1 ));
  277.  
  278.   cnrObject->refreshFromObject( );
  279.   cnrObject->refresh          ( );
  280.  
  281.   if ( refreshOn )
  282.   {
  283.     setRefreshOn( );
  284.     refresh     ( );
  285.   }
  286.  
  287.   INotificationEvent  anEvent(
  288.      IVBContainerControl<Element,Collection,CnrElement>::itemChangedId,
  289.     *this,
  290.      true ,
  291.      IEventData((void *)&element) );
  292.   notifyObservers( anEvent );
  293.  
  294.   return *this;
  295. }
  296.  
  297. template <class Element, class Collection, class CnrElement>
  298.   IVBContainerControl<Element,Collection,CnrElement>&
  299.     IVBContainerControl<Element,Collection,CnrElement> :: collectionReplaced( )
  300. {
  301.   INotificationEvent  anEvent(
  302.      IVBContainerControl<Element,Collection,CnrElement>::itemsId,
  303.     *this,
  304.      true ,
  305.      IEventData( (void *)items( ) ) );
  306.   notifyObservers( anEvent );
  307.  
  308.   return *this;
  309. }
  310.  
  311. template <class Element, class Collection, class CnrElement>
  312.   IVBContainerControl<Element,Collection,CnrElement>&
  313.     IVBContainerControl<Element,Collection,CnrElement>::
  314.       removeSelectedElements ( const Boolean deleteElements )
  315. {
  316.   IVSequence<unsigned long>         removePositions(*selectedCollectionPositions( ));
  317.   IVSequence<Element> *             pSequence = items( );
  318.   IVSequence<unsigned long>::Cursor cursor(removePositions);
  319.   Boolean                           refreshOn = isRefreshOn( ),
  320.                                     itemRemoved = false;
  321.  
  322.  
  323.   setRefreshOff   ( );
  324.  
  325.     fVBContainerControlData->pButton2Elements->removeAll();
  326.     fVBContainerControlData->pSelectedElements->removeAll();
  327.   for ( cursor.setToLast( );
  328.         cursor.isValid ( );
  329.         cursor.setToPrevious ( ) )
  330.   {
  331.     IPosition removePos = removePositions.elementAt ( cursor );
  332.     Element removedElement = pSequence->elementAtPosition ( removePos );
  333.     pSequence->removeAtPosition( removePos );
  334.     itemRemoved = true;
  335.     if (deleteElements)
  336.     {
  337.       delete removedElement;   //assuming pointers
  338.     }
  339.   }
  340.  
  341.   fVBContainerControlData->pSelectedCollectionPositions->removeAll();
  342.   fVBContainerControlData->pButton2CollectionPositions->removeAll();
  343.  
  344.   if (itemRemoved)
  345.   {
  346.     INotificationEvent  anEvent(
  347.        IVBContainerControl<Element,Collection,CnrElement>::selectId,
  348.       *this );
  349.     notifyObservers( anEvent );
  350.  
  351.     INotificationEvent  anEvent2(
  352.        IVBContainerControl<Element,Collection,CnrElement>::button2PointId,
  353.       *this );
  354.     notifyObservers( anEvent2 );
  355.   }
  356.  
  357.   if ( refreshOn )
  358.   {
  359.     setRefreshOn( );
  360.     refresh     ( );
  361.   }
  362.  
  363.   return *this;
  364. }
  365.  
  366. template <class Element, class Collection, class CnrElement>
  367.   IVBContainerControl<Element,Collection,CnrElement>&
  368.     IVBContainerControl<Element,Collection,CnrElement>::
  369.       removeButton2Elements ( const Boolean deleteElements )
  370. {
  371.   IVSequence<unsigned long> *       removePositions = button2CollectionPositions( );
  372.   IVSequence<Element> *             pSequence = items( );
  373.   IVSequence<unsigned long>::Cursor cursor(*removePositions);
  374.   Boolean                           refreshOn = isRefreshOn( ),
  375.                                     itemRemoved = false;
  376.  
  377.   setRefreshOff   ( );
  378.  
  379.   fVBContainerControlData->pButton2Elements->removeAll();
  380.   fVBContainerControlData->pSelectedElements->removeAll();
  381.   for ( cursor.setToLast( );
  382.         cursor.isValid ( );
  383.         cursor.setToPrevious ( ) )
  384.   {
  385.     IPosition removePos = removePositions->elementAt ( cursor );
  386.     Element removedElement = pSequence->elementAtPosition ( removePos );
  387.     pSequence->removeAtPosition( removePos );
  388.     itemRemoved = true;
  389.     if (deleteElements)
  390.     {
  391.       delete removedElement;   //assuming pointers
  392.     }
  393.   }
  394.  
  395.   fVBContainerControlData->pSelectedCollectionPositions->removeAll();
  396.   fVBContainerControlData->pButton2CollectionPositions->removeAll();
  397.  
  398.   if (itemRemoved)
  399.   {
  400.     INotificationEvent  anEvent(
  401.        IVBContainerControl<Element,Collection,CnrElement>::selectId,
  402.       *this );
  403.     notifyObservers( anEvent );
  404.  
  405.     INotificationEvent  anEvent2(
  406.        IVBContainerControl<Element,Collection,CnrElement>::button2PointId,
  407.       *this );
  408.     notifyObservers( anEvent2 );
  409.   }
  410.  
  411.   if ( refreshOn )
  412.   {
  413.     setRefreshOn( );
  414.     refresh     ( );
  415.   }
  416.  
  417.   return *this;
  418. }
  419.  
  420. template <class Element, class Collection, class CnrElement>
  421.   IVBContainerControl<Element,Collection,CnrElement>&
  422.     IVBContainerControl<Element,Collection,CnrElement>::
  423.       removeAllElements ( const Boolean deleteElements )
  424. {
  425.   IVSequence<Element> *             pSequence = items( );
  426.   Boolean                           refreshOn = isRefreshOn( );
  427.  
  428.   setRefreshOff   ( );
  429.  
  430.   fVBContainerControlData->pButton2Elements->removeAll();
  431.   fVBContainerControlData->pSelectedElements->removeAll();
  432.  
  433.   while ( !(pSequence->isEmpty()) )
  434.   {
  435.     Element removedElement = pSequence->firstElement();
  436.     pSequence->removeFirst();
  437.     if (deleteElements)
  438.     {
  439.       //Notification must be disabled so that element observers don't trap on the deleteId
  440.       removedElement->disableNotification();
  441.       delete removedElement;   //assuming pointers
  442.     }
  443.   }
  444.  
  445.   fVBContainerControlData->pSelectedCollectionPositions->removeAll();
  446.   fVBContainerControlData->pButton2CollectionPositions->removeAll();
  447.  
  448.   INotificationEvent  anEvent(
  449.      IVBContainerControl<Element,Collection,CnrElement>::selectId,
  450.     *this );
  451.   notifyObservers( anEvent );
  452.  
  453.   INotificationEvent  anEvent2(
  454.      IVBContainerControl<Element,Collection,CnrElement>::button2PointId,
  455.     *this );
  456.   notifyObservers( anEvent2 );
  457.  
  458.   if ( refreshOn )
  459.   {
  460.     setRefreshOn( );
  461.     refresh     ( );
  462.   }
  463.   return *this;
  464. }
  465.  
  466. template <class Element, class Collection, class CnrElement>
  467.   unsigned long IVBContainerControl<Element,Collection,CnrElement>::
  468.     selectedCollectionPosition ( )
  469. {
  470.   unsigned long                    collectionPosition;
  471.   IPartOrderedCollection<Element>* aCollection = items( );
  472.   IVBContainerControl<Element,Collection,CnrElement>::ObjectCursor cursor( *this );
  473.   Boolean                          proceed;
  474.   IContainerObject*                cnrObject;
  475.  
  476.   for ( cursor.setToFirst( ), collectionPosition = 0, proceed = true;
  477.         cursor.isValid   ( ) && proceed;
  478.         cursor.setToNext ( ), collectionPosition++ )
  479.   {
  480.     cnrObject = objectAt( cursor );
  481.     if ( isSelected( cnrObject ) )
  482.       proceed = false;
  483.   }
  484.  
  485.   if ( ( aCollection->numberOfElements() < collectionPosition ) || proceed )
  486.     collectionPosition =
  487.       IVBContainerControl<Element,Collection,CnrElement>::noSelection;
  488.  
  489.   return collectionPosition;
  490.  
  491. }
  492.  
  493. template <class Element, class Collection, class CnrElement>
  494.   unsigned long IVBContainerControl<Element,Collection,CnrElement>::
  495.     cursoredCollectionPosition ( )
  496. {
  497.   unsigned long      collectionPosition;
  498.   IVBContainerControl<Element,Collection,CnrElement>::ObjectCursor cursor( *this );
  499.   Boolean            proceed;
  500.   IContainerObject*  cnrObject;
  501.  
  502.   for ( cursor.setToFirst( ), collectionPosition = 0, proceed = true;
  503.         cursor.isValid   ( ) && proceed;
  504.         cursor.setToNext ( ), collectionPosition++ )
  505.   {
  506.     cnrObject = objectAt( cursor );
  507.     if ( isCursored( cnrObject ) )
  508.       proceed = false;
  509.   }
  510.  
  511.   if ( proceed )
  512.     collectionPosition =
  513.       IVBContainerControl<Element,Collection,CnrElement>::noSelection;
  514.  
  515.   return collectionPosition;
  516.  
  517. }
  518.  
  519. template <class Element, class Collection, class CnrElement>
  520.   unsigned long IVBContainerControl<Element,Collection,CnrElement>::
  521.     button2CollectionPosition ( )
  522. {
  523.   unsigned long      collectionPosition;
  524.   IVBContainerControl<Element,Collection,CnrElement>::ObjectCursor cursor( *this );
  525.   Boolean            proceed;
  526.   IContainerObject*  cnrObject;
  527.   IContainerObject*  button2CnrObject = objectUnderPoint( button2Point() );
  528.  
  529.   for ( cursor.setToFirst( ), collectionPosition = 0, proceed = true;
  530.         cursor.isValid   ( ) && proceed;
  531.         cursor.setToNext ( ), collectionPosition++ )
  532.   {
  533.     cnrObject = objectAt( cursor );
  534.     if ( cnrObject == button2CnrObject )
  535.       proceed = false;
  536.   }
  537.  
  538.   if ( proceed )
  539.     collectionPosition =
  540.       IVBContainerControl<Element,Collection,CnrElement>::noSelection;
  541.  
  542.   return collectionPosition;
  543. }
  544.  
  545. template <class Element, class Collection, class CnrElement>
  546.  IVSequence<Element> *
  547.    IVBContainerControl<Element,Collection,CnrElement>::
  548.      selectedElements ( )
  549. {
  550.   return selectedElements(fVBContainerControlData->pSelectedElements);
  551. }
  552.  
  553. template <class Element, class Collection, class CnrElement>
  554.  IVSequence<Element> *
  555.    IVBContainerControl<Element,Collection,CnrElement>::
  556.      selectedElements ( IVSequence<Element> & aSequence)
  557. {
  558.   IPartOrderedCollection<Element>* pSequence = items                ( );
  559.   IContainerControl::ObjectCursor  cursor( *this );
  560.  
  561.   unsigned long index = 0;
  562.   aSequence.removeAll( );
  563.  
  564.   forCursor( cursor )
  565.   {
  566.     index++;
  567.     IContainerObject *cnrObject = objectAt( cursor );
  568.     if ( isSelected( cnrObject ) )
  569.     {
  570.       aSequence.add( pSequence->elementAtPosition( index ) );
  571.     }
  572.   }
  573.   return &aSequence;
  574. }
  575.  
  576. template <class Element, class Collection, class CnrElement>
  577.  IVSequence<Element> *
  578.    IVBContainerControl<Element,Collection,CnrElement>::
  579.      selectedElements ( IVSequence<Element> * aSequence)
  580. {
  581.   return selectedElements( *aSequence );
  582. }
  583.  
  584. template <class Element, class Collection, class CnrElement>
  585.  IVSequence<Element> *
  586.    IVBContainerControl<Element,Collection,CnrElement>::
  587.      button2Elements ( )
  588. {
  589.   IVSequence<Element> * pBut2Col = fVBContainerControlData->pButton2Elements;
  590.  
  591.   if ( !(button2Point() == IPoint()) )
  592.   {
  593.     IContainerObject* button2CnrObject = objectUnderPoint(button2Point());
  594.      if (button2CnrObject)
  595.      {
  596.        if ( isSelected(button2CnrObject) )
  597.        {
  598.          return selectedElements( pBut2Col );
  599.        }
  600.        else
  601.        {
  602.          pBut2Col->removeAll( );
  603.          pBut2Col->add( button2Element() );
  604.        }
  605.      }
  606.      else
  607.        //clear the collection if no object is under the pointer
  608.        pBut2Col->removeAll( );
  609.   }
  610.   return pBut2Col;
  611. }
  612.  
  613. template <class Element, class Collection, class CnrElement>
  614.   IVSequence<unsigned long> *
  615.     IVBContainerControl<Element,Collection,CnrElement>::
  616.       selectedCollectionPositions ( )
  617. {
  618.   return selectedCollectionPositions(fVBContainerControlData->pSelectedCollectionPositions);
  619. }
  620.  
  621. template <class Element, class Collection, class CnrElement>
  622.   IVSequence<unsigned long> *
  623.     IVBContainerControl<Element,Collection,CnrElement>::
  624.       selectedCollectionPositions ( IVSequence<unsigned long> * aSequence)
  625. {
  626.   IContainerControl::ObjectCursor  cursor ( *this );
  627.   unsigned long index = 0;
  628.  
  629.   aSequence->removeAll( );
  630.  
  631.   forCursor( cursor )
  632.   {
  633.     index++;
  634.     IContainerObject *cnrObject = objectAt( cursor );
  635.     if ( isSelected( cnrObject ) )
  636.       aSequence->add( index );
  637.   }
  638.   return aSequence;
  639. }
  640.  
  641. template <class Element, class Collection, class CnrElement>
  642.   IVSequence<unsigned long> *
  643.     IVBContainerControl<Element,Collection,CnrElement>::
  644.       button2CollectionPositions  ( )
  645. {
  646.   IVSequence<unsigned long> * pColPositions = fVBContainerControlData->pButton2CollectionPositions;
  647.  
  648.   if ( !(button2Point() == IPoint()) )
  649.   {
  650.     IContainerObject* button2CnrObject = objectUnderPoint(button2Point());
  651.      if (button2CnrObject)
  652.      {
  653.        if ( isSelected(button2CnrObject) )
  654.        {
  655.          return selectedCollectionPositions( pColPositions );
  656.        }
  657.        else
  658.        {
  659.          pColPositions->removeAll( );
  660.          pColPositions->add( button2CollectionPosition() );
  661.        }
  662.      }
  663.      else
  664.        //clear the collection if no object is under the pointer
  665.        pColPositions->removeAll( );
  666.   }
  667.   return pColPositions;
  668. }
  669.  
  670. template <class Element, class Collection, class CnrElement>
  671.   IVBContainerControl<Element,Collection,CnrElement>&
  672.     IVBContainerControl<Element,Collection,CnrElement>::
  673.       select ( unsigned long collectionPosition ,
  674.                Boolean       select )
  675. {
  676.   IContainerObject* cnrObject;
  677.  
  678.   if ( ( collectionPosition > 0 ) &&
  679.        ( collectionPosition <= IContainerControl::objectCount( ) ) )
  680.   {
  681.     cnrObject = objectAt( collectionPosition - 1 );
  682.     setSelected( cnrObject, select );
  683.   }
  684.  
  685.   return *this;
  686. }
  687.  
  688. template <class Element, class Collection, class CnrElement>
  689.   IVBContainerControl<Element,Collection,CnrElement>&
  690.     IVBContainerControl<Element,Collection,CnrElement>::
  691.       deselect ( unsigned long collectionPosition )
  692. {
  693.   return select( collectionPosition, false );
  694. }
  695.  
  696. template <class Element, class Collection, class CnrElement>
  697.   Element       IVBContainerControl<Element,Collection,CnrElement>::
  698.     selectedElement ( )
  699. {
  700.   unsigned long                    selectedPosition;
  701.   IPartOrderedCollection<Element>* aCollection = items( );
  702.   IAutoPointer<ICursor>            pCursor( aCollection->newCursor( ), IINIT );
  703.  
  704.   selectedPosition = selectedCollectionPosition( );
  705.   if ( selectedPosition ==
  706.          IVBContainerControl<Element,Collection,CnrElement>::noSelection )
  707.   {
  708.     ITHROWLIBRARYERROR( IC_NO_SELECTION,
  709.                         IBaseErrorInfo::invalidRequest,
  710.                         IException::recoverable );
  711.   }
  712.  
  713.   aCollection->setToPosition   ( selectedPosition, *pCursor );
  714.   return aCollection->elementAt( *pCursor );
  715. }
  716.  
  717. template <class Element, class Collection, class CnrElement>
  718.   Element       IVBContainerControl<Element,Collection,CnrElement>::
  719.     button2Element ( )
  720. {
  721.   unsigned long                    button2Position;
  722.   IPartOrderedCollection<Element>* aCollection = items( );
  723.   IAutoPointer<ICursor>            pCursor( aCollection->newCursor( ), IINIT );
  724.  
  725.   button2Position = button2CollectionPosition( );
  726.   if ( button2Position ==
  727.          IVBContainerControl<Element,Collection,CnrElement>::noSelection )
  728.   {
  729.     ITHROWLIBRARYERROR( IC_NO_SELECTION,
  730.                         IBaseErrorInfo::invalidRequest,
  731.                         IException::recoverable );
  732.   }
  733.  
  734.   aCollection->setToPosition   ( button2Position, *pCursor );
  735.   return aCollection->elementAt( *pCursor );
  736. }
  737.  
  738. template <class Element, class Collection, class CnrElement>
  739.   Element       IVBContainerControl<Element,Collection,CnrElement>::
  740.     cursoredElement ( )
  741. {
  742.   unsigned long                    cursoredPosition;
  743.   IPartOrderedCollection<Element>* aCollection = items( );
  744.   IAutoPointer<ICursor>            pCursor( aCollection->newCursor( ), IINIT );
  745.  
  746.   cursoredPosition = cursoredCollectionPosition( );
  747.   if ( cursoredPosition ==
  748.          IVBContainerControl<Element,Collection,CnrElement>::noSelection )
  749.   {
  750.     ITHROWLIBRARYERROR( IC_NO_SELECTION,
  751.                         IBaseErrorInfo::invalidRequest,
  752.                         IException::recoverable );
  753.   }
  754.  
  755.   aCollection->setToPosition   ( cursoredPosition, *pCursor );
  756.   return aCollection->elementAt( *pCursor );
  757. }
  758.  
  759. template <class Element, class Collection, class CnrElement>
  760.   CnrElement*  IVBContainerControl<Element,Collection,CnrElement>::
  761.     selectedCnrObject ( )
  762. {
  763.   IContainerControl::ObjectCursor  cursor( *this,
  764.                                            IContainerObject::selected  );
  765.  
  766.   cursor.setToFirst   ( );
  767.   if ( !cursor.isValid( ) )
  768.   {
  769.     ITHROWLIBRARYERROR( IC_NO_SELECTION,
  770.                         IBaseErrorInfo::invalidRequest,
  771.                         IException::recoverable );
  772.   }
  773.  
  774.   return (CnrElement *)objectAt( cursor );
  775.  
  776. }
  777.  
  778. template <class Element, class Collection, class CnrElement>
  779.   IVSequence<IContainerObject *> *
  780.     IVBContainerControl<Element,Collection,CnrElement>::
  781.       selectedCnrObjects  ( IVSequence<IContainerObject *>& cnrObjects )
  782. {
  783.   IPartOrderedCollection<Element>* pSequence = items                ( );
  784.  
  785.   IContainerControl::ObjectCursor  cursor( *this,
  786.                                            IContainerObject::selected  );
  787.  
  788.   cnrObjects.removeAll( );
  789.  
  790.   forCursor( cursor )
  791.     cnrObjects.add( objectAt( cursor ) );
  792.  
  793.   return &cnrObjects;
  794. }
  795.  
  796. template <class Element, class Collection, class CnrElement>
  797.   IVSequence<IContainerObject *> *
  798.     IVBContainerControl<Element,Collection,CnrElement>::
  799.       selectedCnrObjects  ( IVSequence<IContainerObject *>* cnrObjects )
  800. {
  801.   return selectedCnrObjects( *cnrObjects );
  802. }
  803.  
  804. template <class Element, class Collection, class CnrElement>
  805.   IVSequence<IContainerObject *> *
  806.     IVBContainerControl<Element,Collection,CnrElement>::
  807.       selectedCnrObjects  ( )
  808. {
  809.   return selectedCnrObjects( fVBContainerControlData->pSelectedCnrObjects );
  810. }
  811.  
  812. template <class Element, class Collection, class CnrElement>
  813.   IVSequence<IContainerObject *> *
  814.     IVBContainerControl<Element,Collection,CnrElement>::
  815.       button2CnrObjects  ( )
  816. {
  817.   IVSequence<IContainerObject *> * pBut2Col = fVBContainerControlData->pButton2CnrObjects;
  818.  
  819.   if ( !(button2Point() == IPoint()) )
  820.   {
  821.     CnrElement * button2CnrObject = (CnrElement *) objectUnderPoint(button2Point());
  822.     if (button2CnrObject)
  823.      {
  824.        if ( isSelected(button2CnrObject) )
  825.        {
  826.          return selectedCnrObjects( pBut2Col );
  827.        }
  828.        else
  829.        {
  830.          pBut2Col->removeAll( );
  831.          pBut2Col->add( button2CnrObject );
  832.        }
  833.      }
  834.      else
  835.        //clear the collection if no object is under the pointer
  836.        pBut2Col->removeAll( );
  837.   }
  838.   return pBut2Col;
  839. }
  840.  
  841. template <class Element, class Collection, class CnrElement>
  842.   unsigned long IVBContainerControl<Element,Collection,CnrElement>::
  843.     numberOfSelections ( ) const
  844. {
  845.   unsigned long                    count = 0;
  846.   IContainerControl::ObjectCursor  cursor( *this,
  847.                                            IContainerObject::selected  );
  848.   forCursor ( cursor )
  849.     count++;
  850.  
  851.   return count;
  852. }
  853.  
  854. template <class Element, class Collection, class CnrElement>
  855.   unsigned long IVBContainerControl<Element,Collection,CnrElement>::
  856.     numberOfButton2Objects ( ) const
  857. {
  858.   if ( !(button2Point() == IPoint()) )
  859.   {
  860.     IContainerObject* button2CnrObject = objectUnderPoint(button2Point());
  861.      if (button2CnrObject)
  862.      {
  863.        if ( isSelected(button2CnrObject) )
  864.          return numberOfSelections( );
  865.        else
  866.          return 1;
  867.      }
  868.   }
  869.   return 0;
  870. }
  871.  
  872. template <class Element, class Collection, class CnrElement>
  873.   IVBContainerControl<Element,Collection,CnrElement> & IVBContainerControl<Element,Collection,CnrElement>::
  874.     setButton2Point(const IPoint & aPoint)
  875. {
  876.   fVBContainerControlData->fButton2Point = aPoint;
  877.  
  878.   INotificationEvent  anEvent(
  879.      IVBContainerControl<Element,Collection,CnrElement>::button2PointId,
  880.      *this,
  881.      true ,
  882.      IEventData((void *) &(fVBContainerControlData->fButton2Point)) );
  883.   notifyObservers( anEvent );
  884.   return *this;
  885. }
  886.  
  887. template <class Element, class Collection, class CnrElement>
  888.   IPoint IVBContainerControl<Element,Collection,CnrElement>::
  889.     button2Point() const
  890. {
  891.   return fVBContainerControlData->fButton2Point;
  892. }
  893.  
  894. template <class Element, class Collection, class CnrElement>
  895.   void IVBContainerControl<Element,Collection,CnrElement>::
  896.     initialize ( )
  897. {
  898.   fVBContainerControlData = new
  899.       IVBContainerControlData< Element, IVBContainerControl<Element,Collection,CnrElement>, Collection> ( );
  900.   fVBContainerControlData->fCollectionViewData->fCollectionObserver.setViewer( this );
  901.   fVBContainerControlData->pSelectedElements   = new IVSequence<Element>;
  902.   fVBContainerControlData->pButton2Elements    = new IVSequence<Element>;
  903.   fVBContainerControlData->pSelectedCnrObjects = new IVSequence<IContainerObject *>;
  904.   fVBContainerControlData->pButton2CnrObjects  = new IVSequence<IContainerObject *>;
  905.   fVBContainerControlData->pSelectedCollectionPositions = new IVSequence<unsigned long>;
  906.   fVBContainerControlData->pButton2CollectionPositions  = new IVSequence<unsigned long>;
  907.   fVBContainerControlData->pMouseHandler = new
  908.     IVBContainerMouseHandler< IVBContainerControl<Element,Collection,CnrElement> >(this);
  909.   enableNotification     ( );
  910.   fVBContainerControlData->pSelectedElements->enableNotification();
  911.   fVBContainerControlData->pButton2Elements->enableNotification();
  912.   fVBContainerControlData->pSelectedCnrObjects->enableNotification();
  913.   fVBContainerControlData->pButton2CnrObjects->enableNotification();
  914.   fVBContainerControlData->pSelectedCollectionPositions->enableNotification();
  915.   fVBContainerControlData->pButton2CollectionPositions->enableNotification();
  916.   setDeleteObjectsOnClose( );
  917. }
  918.  
  919. template <class Element, class Collection, class CnrElement>
  920.   const unsigned long
  921.     IVBContainerControl<Element,Collection,CnrElement>::firstItem   = 1;
  922. template <class Element, class Collection, class CnrElement>
  923.   const unsigned long
  924.     IVBContainerControl<Element,Collection,CnrElement>::noSelection = 0;
  925.  
  926.  
  927. IVBContainerObject::IVBContainerObject( const IString&        string,
  928.                                         const IPointerHandle& iconHandle )
  929.                     : IContainerObject( string, iconHandle )
  930. { }
  931.  
  932. IVBContainerObject& IVBContainerObject::
  933.   operator= ( const IVBContainerObject& aObject )
  934. {
  935.   if (this == &aObject)
  936.   {
  937.     return *this;
  938.   }
  939.  
  940.   setIcon    ( aObject.icon    ( ) );
  941.   setIconText( aObject.iconText( ) );
  942.   return *this;
  943. }
  944.  
  945. IString IVBContainerObject::asString( ) const
  946. {
  947.   return iconText();
  948. }
  949.