home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / yacl-012.zip / ui / strview.cxx < prev    next >
C/C++ Source or Header  |  1995-04-04  |  21KB  |  734 lines

  1.  
  2.  
  3.  
  4.  
  5.  
  6. /*
  7.  *
  8.  *          Copyright (C) 1994, M. A. Sridhar
  9.  *  
  10.  *
  11.  *     This software is Copyright M. A. Sridhar, 1994. You are free
  12.  *     to copy, modify or distribute this software  as you see fit,
  13.  *     and to use  it  for  any  purpose, provided   this copyright
  14.  *     notice and the following   disclaimer are included  with all
  15.  *     copies.
  16.  *
  17.  *                        DISCLAIMER
  18.  *
  19.  *     The author makes no warranties, either expressed or implied,
  20.  *     with respect  to  this  software, its  quality, performance,
  21.  *     merchantability, or fitness for any particular purpose. This
  22.  *     software is distributed  AS IS.  The  user of this  software
  23.  *     assumes all risks  as to its quality  and performance. In no
  24.  *     event shall the author be liable for any direct, indirect or
  25.  *     consequential damages, even if the  author has been  advised
  26.  *     as to the possibility of such damages.
  27.  *
  28.  */
  29.  
  30.  
  31. #if defined(__GNUC__)
  32. #pragma implementation
  33. #endif
  34.  
  35.  
  36.  
  37. #if defined(__MS_WINDOWS__)
  38. #include <windows.h>
  39.  
  40. #elif defined(__X_MOTIF__)
  41. #include <Xm/Frame.h>
  42. #include <Xm/BulletinB.h>
  43. #include <Xm/List.h>
  44.  
  45. #endif
  46.  
  47. #include "ui/strview.h"
  48. #include "ui/cntroler.h"
  49. #include "ui/event.h"
  50. #include "ui/applic.h"
  51.  
  52. #include "base/intset.h"
  53.  
  54.  
  55.  
  56. #if defined(__MS_WINDOWS__)
  57. #define LISTBOX_STYLE LBS_NOTIFY | LBS_USETABSTOPS | WS_CHILD | WS_VISIBLE \
  58.         | WS_BORDER | WS_HSCROLL | WS_VSCROLL | WS_TABSTOP
  59. #elif defined(__OS2__)
  60. #define LISTBOX_STYLE LS_HORZSCROLL | WS_VISIBLE
  61. #endif
  62.  
  63.  
  64. typedef CL_Binding<UI_StringView> StrViewBind;
  65.  
  66. #if defined(__GNUC__)
  67. template class CL_Binding<UI_StringView>;
  68. #endif
  69.  
  70.  
  71.  
  72. UI_StringView::UI_StringView
  73.     (UI_VObjCollection* p, UI_StringSequence* model,
  74.      const UI_Rectangle& shape, bool mult, UI_ViewID id, long s)
  75. : UI_SimpleVObject (p, shape, id, s)
  76. {   
  77.     _multiple = mult;
  78.     _model    = model;
  79.     _ownModel = FALSE;
  80. #if defined(__MS_WINDOWS__)
  81.     if (_style == -1)
  82.         _style = LISTBOX_STYLE;
  83.     if (_multiple)
  84.         _style |= LBS_MULTIPLESEL;
  85. #elif defined(__OS2__)
  86.     _style = LISTBOX_STYLE;
  87.     if (_multiple)
  88.         _style |= LS_MULTIPLESEL | LS_EXTENDEDSEL;
  89. #elif defined(__X_MOTIF__)
  90.     _frame = NULL;
  91. #endif
  92. }
  93.  
  94.  
  95.  
  96. UI_StringView::UI_StringView
  97.     (UI_VObjCollection* p, const UI_Rectangle& shape,
  98.      bool mult, UI_ViewID id, long s
  99.     )
  100. : UI_SimpleVObject (p, shape, id, s)
  101. {  
  102.     _model = new UI_StringSequence; 
  103.     _multiple = mult;
  104. #if defined(__MS_WINDOWS__)
  105.     if ( _style == -1 )
  106.         _style = LISTBOX_STYLE;
  107.     if ( _multiple )
  108.         _style |= LBS_MULTIPLESEL;
  109.  
  110. #elif defined(__OS2__)
  111.     _style = LISTBOX_STYLE;
  112.     if (_multiple)
  113.         _style |= LS_MULTIPLESEL | LS_EXTENDEDSEL;
  114. #elif defined(__X_MOTIF__)
  115.     _frame = NULL;
  116. #endif
  117. }
  118.  
  119.  
  120. void UI_StringView::ScrollTo (long index)
  121. {
  122. #if defined(__MS_WINDOWS__)
  123.     if (_handle && index >= 0)
  124.         SendMessage (_handle, LB_SETTOPINDEX, (WORD) index, 0);
  125. #elif defined(__OS2__)
  126.     if (_handle && index >= 0)
  127.         WinSendMsg (_handle, LM_SETTOPINDEX, (MPARAM) index, 0);
  128. #elif defined(__X_MOTIF__)
  129.     if (_xwidget && index >= 0)
  130.         XmListSetPos (_xwidget, index-1);
  131. #endif
  132. }
  133.  
  134. #if defined(__MS_WINDOWS__)
  135. UI_StringView::UI_StringView
  136.     (UI_CompositeVObject* p, UI_ViewID id, UI_ViewHandle h)
  137. : UI_SimpleVObject (p, id, h)
  138. {
  139.     _model = new UI_StringSequence;
  140.     ((UI_StringSequence*) _model)->AddClient (this);
  141. }
  142. #endif
  143.  
  144.  
  145.  
  146. UI_StringView::~UI_StringView ()
  147. {
  148.     ((UI_StringSequence*) _model)->RemoveClient (this);
  149. #if defined(__X_MOTIF__)
  150.     if (_frame)
  151.         XtDestroyWidget (_frame);
  152. #endif
  153. }
  154.  
  155.  
  156. long UI_StringView::TopIndex () const
  157. {
  158. #if defined(__MS_WINDOWS__)
  159.     return _handle ? SendMessage (_handle, LB_GETTOPINDEX, 0, 0) : -1;
  160. #elif defined(__OS2__)
  161.     return _handle ? (long) WinSendMsg (_handle, LM_QUERYTOPINDEX, 0, 0) : -1;
  162. #elif defined(__X_MOTIF)
  163.     int pos;
  164.     XtGetValues (_handle, XmNtopItemPosition, &pos);
  165.     return pos-1;
  166. #endif
  167. }
  168.  
  169.  
  170. short UI_StringView::VisibleCount () const
  171. {
  172. #if defined(__MS_WINDOWS__)
  173.     if (!_handle)
  174.         return 0;
  175.     long h = SendMessage (_handle, LB_GETITEMHEIGHT, 0, 0);
  176.     return h > 0 ? _shape.Height() / h : 0;
  177. #elif defined(__OS2__)
  178.     NotImplemented ("VisibleCount");
  179.     return 0;
  180. #elif defined(__X_MOTIF)
  181.     int size;
  182.     XtGetValues (_handle, XmNvisibleItemCount, &size);
  183.     return size;
  184. #endif
  185. }
  186.  
  187.  
  188.  
  189. void UI_StringView::MakeVisible ()
  190. {
  191. #if defined(__X_MOTIF__)
  192.     if (_frame)
  193.         XtManageChild   (_frame);
  194. #endif
  195.     UI_SimpleVObject::MakeVisible ();
  196. }
  197.  
  198. void UI_StringView::MakeInvisible ()
  199. {
  200. #if defined(__X_MOTIF__)
  201.     if (_frame)
  202.         XtUnmanageChild   (_frame);
  203. #endif
  204.     UI_SimpleVObject::MakeInvisible ();
  205. }
  206.  
  207.  
  208. #if defined(__X_MOTIF__)
  209. void UI_StringView::_SetupStyle (void* p, short& argn)
  210. {
  211.     Arg* arg = (Arg*) p;
  212.  
  213.     UI_SimpleVObject::_SetupStyle (arg, argn);
  214.     // Add more resource specs:
  215.     XtSetArg (arg [ argn ], XmNlistSizePolicy, XmCONSTANT);     argn++;
  216.     XtSetArg (arg [ argn ], XmNselectionPolicy,
  217.               _multiple ? XmMULTIPLE_SELECT : XmSINGLE_SELECT); argn++;
  218.     // -------------------  ^^^^^^^^ ---------------------
  219.     // If I use EXTENDED_SELECT, then the setting of selection under program
  220.     // control doesn't seem to work right. If The MultiSel box's Selection()
  221.     // is assigned to, only the highest-indexed one of the strings gets
  222.     // highlighted, even though the selection set contains several indices.
  223. }
  224. #endif
  225.  
  226.  
  227.  
  228.  
  229. bool UI_StringView::MakeVisualElement ()
  230. {
  231. #if defined(__MS_WINDOWS__) || defined(__OS2__)
  232.     return UI_SimpleVObject::MakeVisualElement();
  233. #elif defined(__X_MOTIF__)
  234.  
  235.     // This code is copied from that of SimpleVObject, except that we use
  236.     // XmCreateScrolledList instead of XtCreateWidget, because the scroll
  237.     // bar does not seem to be displayed otherwise.
  238.     //
  239.     // There is one other thing. Motif seems to
  240.     // have a strange bug. If we make a List invisible, and create other
  241.     // visible widgets in the same area, the latter are not painted! So we
  242.     // interpose a dummy frame widget of which the List is made a
  243.     // child. This dummy widget is the instance variable _frame.
  244.     
  245.     // GNU C seems to have a strange bug, so we work around it. Instead of
  246.     // saying
  247.     //    Widget pw = (Widget) (_parent->ViewHandle());
  248.     // we say
  249.     UI_VisualObject* p = _parent;
  250.     Widget pw = (Widget) p->ViewHandle();
  251.  
  252.     Arg arg [20];
  253.     short argn = 0;
  254.     // First, we'll create a Frame widget
  255.     CL_String instance_name = InstanceName();
  256.     const char* inst_name   = instance_name.AsPtr();
  257.     CL_String frame_name    = instance_name  + "_frame";
  258.  
  259.     short x = _shape.Left   ();
  260.     short y = _shape.Top    ();
  261.     short w = _shape.Width  ();
  262.     short h = _shape.Height ();
  263.  
  264.     XtSetArg (arg [ argn ], XtNx,     x); argn++;
  265.     XtSetArg (arg [ argn ], XtNy,     y); argn++;
  266.     XtSetArg (arg [ argn ], XtNheight,h); argn++;
  267.     XtSetArg (arg [ argn ], XtNwidth, w); argn++;
  268.     XtSetArg (arg [argn], XmNmarginWidth,  0);     argn++;
  269.     XtSetArg (arg [argn], XmNmarginHeight, 0);     argn++;
  270.     _frame = XtCreateWidget (frame_name.AsPtr(), xmFrameWidgetClass,
  271.                              pw, arg, argn);
  272.  
  273.     XtRealizeWidget (_frame);
  274.     // Next, create the List as child of the frame
  275.     _WidgetClassRec* class_name = WindowClass ();
  276.  
  277.     argn = 0;
  278.     _SetupStyle (arg, argn); // Set up the X resources
  279.  
  280.     XmString title = XmStringCreate
  281.         ((char *) _title.AsPtr (), XmSTRING_DEFAULT_CHARSET);    
  282.     XtSetArg (arg [argn], XmNlabelString, title); argn++;
  283.     // _xwidget = XtCreateWidget (inst_name, class_name, pw, arg, argn);
  284.     _xwidget = XmCreateScrolledList (_frame, (char*) inst_name, arg, argn);
  285.     // XtManageChild (_xwidget);
  286.     // XtSetValues (_xwidget, arg, argn);
  287.  
  288.     XmStringFree (title);
  289.     return TRUE;
  290. #endif
  291. }
  292.  
  293.  
  294.  
  295.  
  296.  
  297.  
  298. void UI_StringView::ItemInserted (long i)
  299. {
  300.     CL_String s = (*(UI_StringSequence*) _model) [i+1];
  301.  
  302. #if defined(__MS_WINDOWS__)
  303.     if (_handle)
  304.         SendMessage (_handle, LB_INSERTSTRING, i+1, (long)(const char*)s);
  305. #elif defined(__OS2__)
  306.     if (_handle)
  307.         WinInsertLboxItem (_handle, i, s.AsPtr());
  308. #elif defined(__X_MOTIF__)
  309.     XmString xs;
  310.     char* item = (char *) s.AsPtr (); // Not const char* because
  311.                                       // XmStringCreate expects char*
  312.     xs = XmStringCreate (item, XmSTRING_DEFAULT_CHARSET);
  313.     XmListAddItem (_xwidget, xs, i+2);
  314.     XmStringFree (xs);
  315. #endif
  316.     _UpdateSelection ();
  317. }
  318.  
  319.  
  320.  
  321. void UI_StringView::ItemRemoved (long i)
  322. {
  323. #if defined(__MS_WINDOWS__)
  324.     if (_handle)
  325.         SendMessage (_handle, LB_DELETESTRING, i, 0L);
  326. #elif defined(__OS2__)
  327.     if (_handle)
  328.         WinDeleteLboxItem (_handle, i);
  329. #elif defined(__X_MOTIF__)
  330.     XmListDeletePos (_xwidget, i+1); 
  331. #endif
  332.     _UpdateSelection ();
  333. }
  334.  
  335.  
  336.  
  337. void UI_StringView::ItemChanged (long i)
  338. {
  339.     CL_String s = (*(UI_StringSequence*)_model)[i];
  340. #if defined(__MS_WINDOWS__)
  341.     SendMessage (_handle, WM_SETREDRAW,  FALSE, 0L);
  342.     SendMessage (_handle, LB_DELETESTRING, i, 0L);
  343.     SendMessage (_handle, LB_INSERTSTRING, i, (long) s.AsPtr());
  344.     SendMessage (_handle, WM_SETREDRAW, TRUE, 0L);
  345. #elif defined(__OS2__)
  346.     if (_handle) {
  347.         WinDeleteLboxItem (_handle, i);
  348.         WinInsertLboxItem (_handle, i, s.AsPtr());
  349.     }
  350. #elif defined(__X_MOTIF__)
  351.     XmListDeletePos (_xwidget, i+1);    
  352.     XmString xs;
  353.     char* item = (char*) s.AsPtr ();
  354.     xs = XmStringCreate (item, XmSTRING_DEFAULT_CHARSET);
  355.     XmListAddItem (_xwidget, xs, i+1);
  356.     XmStringFree (xs);
  357. #endif
  358. }
  359.  
  360.  
  361. void UI_StringView::ModelEmptied ()
  362. {
  363. #if defined(__MS_WINDOWS__)
  364.     if (_handle)
  365.         SendMessage (_handle, LB_RESETCONTENT, 0,     0);
  366. #elif defined(__OS2__)
  367.     if (_handle)
  368.         WinSendMsg (_handle, LM_DELETEALL, 0, 0);
  369. #elif defined(__X_MOTIF__)
  370.     if (_xwidget)
  371.         XmListDeleteAllItems (_xwidget);
  372. #endif    
  373. }
  374.  
  375.  
  376. void UI_StringView::_PrivateInitialize ()
  377. {
  378.     UI_SimpleVObject::_PrivateInitialize ();
  379.     UI_StringSequence& theModel = *(UI_StringSequence*) _model;
  380.     theModel.AddClient (this);
  381.     long n = theModel.Size();
  382. #if defined(__MS_WINDOWS__)
  383.     if (!_visible)
  384.         ShowWindow (_handle, SW_HIDE);
  385.     if (!_enabled)
  386.         EnableWindow (_handle, FALSE);
  387.     if (n) {
  388.         SendMessage (_handle, WM_SETREDRAW,    FALSE, 0);
  389.         SendMessage (_handle, LB_RESETCONTENT, 0,     0);
  390.         for (long i = 0; i < n; i++) {
  391.             SendMessage (_handle, LB_ADDSTRING, 0,
  392.                          (long) theModel[i].AsPtr());
  393.         }
  394.         SendMessage (_handle, WM_SETREDRAW, TRUE, 0L);
  395.     }
  396. #elif defined(__OS2__)
  397.     WinSendMsg (_handle, LM_DELETEALL, 0, 0);
  398.     for (long i = 0; i < n; i++)
  399.         WinInsertLboxItem (_handle, LIT_END, theModel[i].AsPtr());
  400. #elif defined(__X_MOTIF__)
  401.     XtAddCallback (_xwidget, XmNbrowseSelectionCallback, 
  402.                    &UI_StringView::Callback, (XtPointer) this);
  403.     XtAddCallback (_xwidget, XmNsingleSelectionCallback, 
  404.                    &UI_StringView::Callback, (XtPointer) this);
  405.     XtAddCallback (_xwidget, XmNextendedSelectionCallback, 
  406.                    &UI_StringView::Callback, (XtPointer) this);
  407.     XtAddCallback (_xwidget, XmNmultipleSelectionCallback, 
  408.                    &UI_StringView::Callback, (XtPointer) this);
  409.     XtAddCallback (_xwidget, XmNdefaultActionCallback, 
  410.                    &UI_StringView::Callback, (XtPointer) this);
  411.  
  412.     if (n) {
  413.         for (long i = 0; i < n; i++) {
  414.             XmString  xs = XmStringCreate ((char*) theModel[i],
  415.                                            XmSTRING_DEFAULT_CHARSET); 
  416.             XmListAddItem (_xwidget, xs, 0);
  417.             XmStringFree (xs);
  418.         }
  419.     }
  420.     if (_visible) {
  421.         XtManageChild (_frame);
  422.         XtManageChild (_xwidget);
  423.     }
  424.  
  425.     if (!_enabled) {
  426.         XtSetSensitive (_xwidget, FALSE);
  427.         XtSetSensitive (_frame, FALSE);
  428.     }
  429. #endif
  430. }
  431.  
  432.  
  433.  
  434. UI_WindowClass UI_StringView::WindowClass () const
  435. {
  436. #if defined(__MS_WINDOWS__)
  437.     return "listbox";
  438. #elif defined(__OS2__)
  439.     return WC_LISTBOX;
  440. #elif defined(__X_MOTIF__)
  441.     return xmListWidgetClass;
  442. #endif
  443. }
  444.  
  445.  
  446. #if defined (__X_MOTIF__)
  447.  
  448. void UI_StringView::Callback (Widget w, void* client, void* call)
  449. {
  450.     UI_StringView* sv = (UI_StringView *) client;
  451.     XmListCallbackStruct* cb = (XmListCallbackStruct*) call;
  452.     UI_Event* e;
  453.     long pos;
  454.     
  455.     switch (cb->reason) {
  456.  
  457.     case XmCR_SINGLE_SELECT:
  458.     case XmCR_BROWSE_SELECT:
  459.     case XmCR_MULTIPLE_SELECT:
  460.     case XmCR_EXTENDED_SELECT:
  461.         e = new UI_Event (Event_Select, sv, sv);
  462.         if (e)
  463.             _Controller->AddEvent (e);
  464.         break;
  465.  
  466.     case XmCR_DEFAULT_ACTION:
  467.         e = new UI_Event (Event_LButtonDblClk, sv, sv);
  468.         if (e) {
  469.             e->curPos.Origin (UI_Point (cb->event->xbutton.x,
  470.                                         cb->event->xbutton.y));
  471.             _Controller->AddEvent (e);
  472.         }
  473.         break;
  474.  
  475.     default:
  476.         break;
  477.     }
  478.         
  479. }
  480.  
  481. #endif
  482.  
  483.  
  484.  
  485.  
  486.  
  487. // ----------------- Single selection StringViews ----------------------
  488.  
  489. UI_StringViewSingleSel::UI_StringViewSingleSel (UI_VObjCollection* parent,  
  490.                         const UI_Rectangle& shape,
  491.                         UI_ViewID id)
  492. : UI_StringView (parent, shape, FALSE, id), _selection (-1)
  493. {
  494.     StrViewBind bind (this, &UI_StringView::_SelectionChanged);
  495.     _selection.AddDependent (bind, 1); // Notification code is not used
  496. }
  497.  
  498.  
  499.  
  500. UI_StringViewSingleSel::UI_StringViewSingleSel
  501.     (UI_VObjCollection* parent, UI_StringSequence* model,
  502.      const UI_Rectangle& shape, UI_ViewID id)
  503. : UI_StringView (parent, model, shape, FALSE, id), _selection (-1)
  504. {
  505.     StrViewBind bind (this, &UI_StringView::_SelectionChanged);
  506.     _selection.AddDependent (bind, 1); // Notification code is not used
  507. }
  508.  
  509.  
  510.  
  511.  
  512. #if defined(__MS_WINDOWS__)
  513. UI_StringViewSingleSel::UI_StringViewSingleSel
  514.     (UI_CompositeVObject* parent, UI_ViewID id, UI_ViewHandle h)
  515. : UI_StringView (parent, id, h), _selection (-1)
  516. {
  517.     StrViewBind bind (this, &UI_StringView::_SelectionChanged);
  518.     _selection.AddDependent (bind, 1); // Notification code is not used
  519. }
  520.     
  521. #endif
  522.  
  523.  
  524.  
  525. bool UI_StringViewSingleSel::Select ()
  526. {
  527.     // Called in response to Event_Select generated when the user changes a
  528.     // selection
  529.     _UpdateSelection ();
  530.     return FALSE; // So that the parent gets a chance to handle this event
  531. }
  532.  
  533.  
  534.  
  535.  
  536.  
  537. void UI_StringViewSingleSel::_UpdateSelection ()
  538. {
  539.     long pos = 0;
  540. #if defined(__MS_WINDOWS__)
  541.     pos = SendMessage (_handle, LB_GETCURSEL, 0, 0);
  542.     if (pos == LB_ERR)
  543.         pos = -1;
  544. #elif defined(__OS2__)
  545.     pos = (long) WinSendMsg (_handle, LM_QUERYSELECTION, (MPARAM) -1, 0);
  546.     if (pos == LIT_NONE)
  547.         pos = -1;
  548. #elif defined(__X_MOTIF__)
  549.     int* pos_list;
  550.     int  count;
  551.     bool b = XmListGetSelectedPos (_xwidget, &pos_list, &count);
  552.     pos = b ? pos_list[0] - 1 : -1;
  553.     // -----------------^^^^^^ -- Correct for Motif's indexing
  554.     if (b)
  555.         XtFree ((char*) pos_list);
  556. #endif
  557.     StrViewBind bind (this, &UI_StringView::_SelectionChanged);
  558.     _selection.RemoveDependent (bind);
  559.     _selection = pos;
  560.     _selection.AddDependent (bind, 1);
  561. }
  562.  
  563.  
  564.  
  565.  
  566. bool UI_StringViewSingleSel::_SelectionChanged (CL_Object&, long)
  567. {
  568.     UI_StringSequence& theModel = *(UI_StringSequence*) _model;
  569.     if (_selection < 0 || _selection >= theModel.Size()) {
  570.         StrViewBind bind (this, &UI_StringView::_SelectionChanged);
  571.         _selection.RemoveDependent (bind);
  572.         _selection = -1; 
  573.         _selection.AddDependent (bind, 1);
  574.     }
  575. #if defined(__MS_WINDOWS__)
  576.     SendMessage (_handle, LB_SETCURSEL, _selection, 0);
  577. #elif defined(__OS2__)
  578.     if (_handle)
  579.         WinSendMsg (_handle, LM_SELECTITEM, (MPARAM) _selection.Value(),
  580.                     (MPARAM) TRUE);
  581. #elif defined(__X_MOTIF__)
  582.     if (_selection >= 0)
  583.         XmListSelectPos (_xwidget, _selection+1, FALSE);
  584.     else
  585.         XmListDeselectAllItems (_xwidget);
  586. #endif
  587.     return TRUE;
  588. }
  589.  
  590.  
  591.  
  592.  
  593. // ----------------- Multiple selection StringViews ----------------------
  594.  
  595. UI_StringViewMultiSel::UI_StringViewMultiSel (UI_VObjCollection* parent,  
  596.                         const UI_Rectangle& shape,
  597.                         UI_ViewID id)
  598. : UI_StringView (parent, shape, TRUE, id)
  599. {
  600.     StrViewBind bind (this, &UI_StringView::_SelectionChanged);
  601.     _selection.AddDependent (bind, 1); // Notification code is not used
  602. }
  603.  
  604.  
  605.  
  606. UI_StringViewMultiSel::UI_StringViewMultiSel
  607.     (UI_VObjCollection* parent, UI_StringSequence* model,
  608.      const UI_Rectangle& shape, UI_ViewID id)
  609. : UI_StringView (parent, model, shape, TRUE, id)
  610. {
  611.     StrViewBind bind (this, &UI_StringView::_SelectionChanged);
  612.     _selection.AddDependent (bind, 1); // Notification code is not used
  613. }
  614.  
  615.  
  616.  
  617.  
  618. #if defined(__MS_WINDOWS__)
  619. UI_StringViewMultiSel::UI_StringViewMultiSel
  620.     (UI_CompositeVObject* parent, UI_ViewID id, UI_ViewHandle h)
  621. : UI_StringView (parent, id, h)
  622. {
  623.     StrViewBind bind (this, &UI_StringView::_SelectionChanged);
  624.     _selection.AddDependent (bind, 1); // Notification code is not used
  625. }
  626. #endif
  627.  
  628.  
  629.  
  630. bool UI_StringViewMultiSel::Select ()
  631. {
  632.     // Called in response to Event_Select generated when the user changes a
  633.     // selection
  634.     _UpdateSelection ();
  635.     return FALSE; // So that the parent gets a chance to handle this event
  636. }
  637.  
  638.  
  639.  
  640.  
  641. void UI_StringViewMultiSel::_UpdateSelection ()
  642. {
  643.     StrViewBind bind (this, &UI_StringView::_SelectionChanged);
  644.     _selection.RemoveDependent (bind);
  645.     _selection.MakeEmpty ();
  646. #if defined(__MS_WINDOWS__)
  647.     long count = SendMessage (_handle, LB_GETSELCOUNT, 0, 0);
  648.     if (count > 0) {
  649.         int* buf = new int [count]; 
  650.         SendMessage (_handle, LB_GETSELITEMS, count, (long)buf);
  651.         for (long i = 0; i < count; i++)
  652.             _selection.Add (buf[i]);
  653.         delete buf;
  654.     }
  655. #elif defined(__OS2__)
  656.     short index = -1;
  657.     short pos;
  658.     do {
  659.         pos = (short) WinSendMsg (_handle, LM_QUERYSELECTION, (MPARAM)
  660.                                   index, 0);
  661.         if (pos == LIT_NONE) break;
  662.         _selection.Add ((long) pos);
  663.         index = pos+1;
  664.     } while (1);
  665. #elif defined(__X_MOTIF__)
  666.     int* pos_list;
  667.     int  count;
  668.     bool b = XmListGetSelectedPos (_xwidget, &pos_list, &count);
  669.     if (!b)
  670.         count = 0;
  671.     for (long i = 0; i < count; i++)
  672.         _selection.Add (pos_list[i] - 1);
  673.     //  ------------------------^^^^ -- Correct for Motif's indexing
  674.     if (b)
  675.         XtFree ((char*) pos_list);
  676. #endif
  677.     _selection.AddDependent (bind, 1);
  678. }
  679.  
  680.  
  681.  
  682. bool UI_StringViewMultiSel::_SelectionChanged (CL_Object&, long)
  683. {
  684.     // First, get rid of extraneous indices:
  685.     StrViewBind bind (this, &UI_StringView::_SelectionChanged);
  686.     UI_StringSequence& theModel = *(UI_StringSequence*) _model;
  687.     _selection.RemoveDependent (bind);
  688.     _selection *= CL_IntegerSet (0, theModel.Size()-1);
  689.     _selection.AddDependent (bind, 1);
  690.  
  691.     // Now update the display:
  692. #if defined(__MS_WINDOWS__)
  693.     SendMessage (_handle, WM_SETREDRAW, FALSE, 0);
  694.     SendMessage (_handle, LB_SELITEMRANGE, FALSE,
  695.                  MAKELPARAM (0, theModel.Size()-1));
  696.     CL_IntegerSetIterator itr (_selection);
  697.     while (itr.More()) {
  698.         long l = itr.Next();
  699.         SendMessage (_handle, LB_SETSEL, TRUE, MAKELPARAM (l, 0));
  700.     }
  701.     SendMessage (_handle, WM_SETREDRAW, TRUE, 0);
  702. #elif defined(__OS2__)
  703.     short index = -1;
  704.     short pos;
  705.     CL_IntegerSet oldSelection;
  706.     do {
  707.         pos = (short) WinSendMsg (_handle, LM_QUERYSELECTION, (MPARAM)
  708.                                   index, 0);
  709.         if (pos == LIT_NONE) break;
  710.         oldSelection.Add ((long) pos);
  711.         index = pos+1;
  712.     } while (1);
  713.     CL_IntegerSet tmpSet = oldSelection - _selection;
  714.     CL_IntegerSetIterator itr (tmpSet);
  715.     while (itr.More())
  716.         WinSendMsg (_handle, LM_SELECTITEM, (MPARAM) itr.Next(), FALSE);
  717.     tmpSet = _selection - oldSelection;
  718.     itr.Reset ();
  719.     while (itr.More())
  720.         WinSendMsg (_handle, LM_SELECTITEM, (MPARAM) itr.Next(), (MPARAM)
  721.                     TRUE);
  722. #elif defined(__X_MOTIF__)
  723.     XmListDeselectAllItems (_xwidget);
  724.     CL_IntegerSetIterator itr (_selection);
  725.     while (itr.More()) {
  726.         long l = itr.Next();
  727.         XmListSelectPos (_xwidget, l+1, FALSE);
  728.     }
  729. #endif
  730.     return TRUE;
  731. }
  732.  
  733.  
  734.