The MG_Mover code

/*
Class:   MG_Mover
Authors:  Gary White and Jean-Pierre Martel

Based on a Gary White's Form published in the dBase Inc's
   "dbase.programming" newsgroup, May 8th 1999,
   in the thread called "Combo Boxes". Few ideas were taken
   from Dan Howard's ItemMover class.

Purpose:
   Use this object to select items in a list.

This class requires:
   an array called a_Items filled with some items

Methods:

   CountItems: To count the number of items chosen
      and to enable/disable the needed pushbuttons.

   MoveItem: The heart of this custom class. To move items
      from one listbox to the other.

   OnOpen: To populate listbox1 if the needed array doesn't exists.

   Reset: To reset the MG_Mover at its original state.

   Want_All: To select all items.

   The MG_Mover allows multiple selection by default. If you want
   single-click moving, activate the lines presently inactivated in the
   listboxes construction code and block the two lines of code just over
   the lines you revealed. Then use the first version of the MoveItem function
   (instead of the second one).

   When this Custom class is dropped on a form, the Form designer
   will stream a bunch of unnecessary code that can be safely removed:
               with(this.MG_Mover1.P_PLUS)
               value = false
            endwith

The authors accept no responsibility for the use or consequences
of the use of this software.

*/

000  CLASS MG_Mover(ParentObj) of CONTAINER(ParentObj) CUSTOM
001    with(this)
002    onOpen := CLASS::ONOPEN
003    parent.metric := 6 // Pixels
004    borderStyle := 4 // Single
005    width := 474
006    height := 171
007    anchor := 1 // bottom
008    visible := false
009    endwith
 

010  this.RECTANGLE1 = new RECTANGLE(this)
011  with (this.RECTANGLE1)
012    left := 3
013    top := 3
014    width := 467
015    height := 140
016    text := ""
017    border := false
018    borderStyle := 7 // Client
019  endwith
 

020  this.LISTBOX1 = new LISTBOX(this)
021  with (this.LISTBOX1)
022    // onLeftDblClick := {;this.parent.MoveItem(this.parent.listbox1.selected(),true)}
023    multiple := true  // take it out if using single-click moving
024    // onLeftDblClick := {;this.parent.want_all()}
025    // onLeftMouseDown := {;this.parent.MoveItem(this.parent.listbox1.selected(),true)}
026    onRightMouseDown := {;this.parent.want_all()}
027    dataSource := 'ARRAY {"Item No. 1","Item No. 2","Item No. 3"}'
028    height := 109
029    left := 7
030    top := 28
031    width := 213
032    id := 101
033    fontSize := 9
034    borderStyle := 8 // Modal
035  endwith
 

036  this.LISTBOX2 = new LISTBOX(this)
037  with (this.LISTBOX2)
038    // onLeftDblClick := {;this.parent.MoveItem(this.parent.listbox2.selected(),false)}
039    multiple := true  // take it out if using single-click moving
040    // onLeftDblClick := {;this.parent.reset()}
041    // onLeftMouseDown := {;this.parent.MoveItem(this.parent.listbox2.selected(),false)}
042    onRightMouseDown := {;this.parent.reset()}
043    height := 109
044    left := 252
045    top := 28
046    width := 213
047    id := 101
048    fontSize := 9
049    borderStyle := 8 // Modal
050  endwith
 

051  this.T_POSSIBLE = new TEXT(this)
052  with (this.T_POSSIBLE)
053    height := 21
054    left := 7
055    top := 7
056    width := 213
057    colorNormal := "white/black"
058    fontSize := 8
059    fontBold := true
060    text := " List of Possible Items"
061    borderStyle := 8 // Modal
062  endwith
 

063  this.T_FINAL = new TEXT(this)
064  with (this.T_FINAL)
065    height := 21
066    left := 252
067    top := 7
068    width := 213
069    colorNormal := "white/black"
070    fontSize := 8
071    fontBold := true
072    text := " Final List"
073    borderStyle := 8 // Modal
074  endwith
 

075  this.P_PLUS = new PUSHBUTTON(this)
076  with (this.P_PLUS)
077    onClick := {;this.parent.MoveItem(this.parent.listbox1.selected(),true)}
078    height := 14
079    left := 226
080    top := 42
081    width := 21
082    upBitmap := "RESOURCE #854"
083    disabledBitmap := "RESOURCE #864"
084    text := ""
085    value := false
086  endwith
 

087  this.P_ALL = new PUSHBUTTON(this)
088  with (this.P_ALL)
089    onClick := {;this.parent.want_all()}
090    height := 14
091    left := 226
092    top := 59
093    width := 21
094    upBitmap := "RESOURCE #855"
095    disabledBitmap := "RESOURCE #865"
096    text := ""
097    value := false
098  endwith
 

099  this.P_MINUS = new PUSHBUTTON(this)
100  with (this.P_MINUS)
101    onClick := {;this.parent.MoveItem(this.parent.listbox2.selected(),false)}
102    height := 14
103    left := 226
104    top := 80
105    width := 21
106    upBitmap := "RESOURCE #853"
107    disabledBitmap := "RESOURCE #863"
108    text := ""
109    value := false
110  endwith
 

111  this.P_NONE = new PUSHBUTTON(this)
112  with (this.P_NONE)
113    onClick := {;this.parent.reset()}
114    height := 14
115    left := 226
116    top := 98
117    width := 21
118    upBitmap := "RESOURCE #852"
119    disabledBitmap := "RESOURCE #862"
120    text := ""
121    value := false
122  endwith
 

123  this.P_OK = new PUSHBUTTON(this)
124  with (this.P_OK)
125  //  onClick := {;form.close()}
126    height := 16
127    left := 337
128    top := 149
129    width := 65
130    text := "OK"
131    fontSize := 8
132    fontBold := true
133      value := false
134  endwith
 

135  this.P_CANCEL = new PUSHBUTTON(this)
136  with (this.P_CANCEL)
137    onClick := {;form.close()}
138    height := 16
139    left := 406
140    top := 149
141    width := 65
142    text := "Cancel"
143    fontSize := 8
144    fontBold := true
145    value := false
146  endwith
 

147  this.T_MESSAGE = new TEXT(this)
148  with (this.T_MESSAGE)
149    height := 14
150    left := 3
151    top := 149
152    width := 217
153    fontSize := 8
154    borderStyle := 3 // None
155  endwith
 

156  function reset
157    if this.chosen.size # 0
158      this.available = new array( this.a_Items.size )
159      acopy( this.a_Items, this.available )
160      this.chosen=new array()
161      this.listbox1.datasource := this.listbox1.datasource
162      this.listbox2.datasource := this.listbox2.datasource
163      this.countItems()
164      this.listbox1.cursel := 1
165    endif
166    return

/*
167  function MoveItem( cItem, bAdd )   // if you allow single-clicking to move
168    if not empty( cItem)
169      oFrom = iif( bAdd, this.listbox1, this.listbox2 )
170      oTo = iif( bAdd, this.listbox2, this.listbox1 )
171      if bAdd
172        this.chosen.add( cItem )
173        this.chosen.sort()
174        this.available.delete( this.available.scan( cItem ))
175        this.available.size --
176      else
177        this.available.add( cItem )
178        this.available.sort()
179        this.chosen.delete( this.chosen.scan( cItem ))
180        this.chosen.size --
181      endif
182      oFrom.datasource := oFrom.datasource
183      oTo.datasource := oTo.datasource
184      oTo.cursel := 1
185      do while oTo.value # cItem
186        oTo.cursel ++
187      enddo
188      this.countItems()
189    endif
190    return
*/

191  function MoveItem( aItem, bAdd )  // if you allow multiple selection
192    if not empty( aItem)
193      oFrom = iif( bAdd, this.listbox1, this.listbox2 )
194      oTo = iif( bAdd, this.listbox2, this.listbox1 )
195      for i = 1 to aItem.size
196        if bAdd
197          this.chosen.add( aItem[i] )
198          this.chosen.sort()
199          this.available.delete( this.available.scan( aItem[i] ))
200          this.available.size --
201        else
202          this.available.add( aItem[i] )
203          this.available.sort()
204          this.chosen.delete( this.chosen.scan( aItem[i] ))
205          this.chosen.size --
206        endif
207      endfor
208      oFrom.datasource := oFrom.datasource
209      oTo.datasource := oTo.datasource
210      oTo.cursel := 1
211      do while oTo.value # aItem[aItem.size]
212        oTo.cursel ++
213      enddo
214      this.countItems()
215    endif
216    return
 

217  function countItems
218    do case
219      case this.Listbox2.count() = 0
220        this.T_Message.text := "   No item chosen among " + ltrim(str(aLen(this.a_Items,1))) + " possible"
221      case this.Listbox2.count() = 1
222        this.T_Message.text := "   1 item chosen among " + ltrim(str(aLen(this.a_Items,1))) + " possible"
223      otherwise
224        this.T_Message.text := "   " + this.Listbox2.count() + " items chosen among " + ltrim(str(aLen(this.a_Items,1))) + " possible"
225    endcase
226    this.P_Minus.enabled := this.Listbox2.count() > 0
227    this.Listbox2.mousePointer := iif(this.P_Minus.enabled = true, 13, 12)
228    this.P_None.enabled := this.Listbox2.count() > 0
229    this.P_OK.enabled := this.Listbox2.count() > 0
230    this.P_Plus.enabled := this.Listbox1.count() > 0
231    this.Listbox1.mousePointer := iif(this.P_Plus.enabled = true, 13, 12)
232    this.P_All.enabled := this.Listbox1.count() > 0
233    return
 

234  function want_All
235    if this.available.size # 0
236      this.chosen.resize(this.a_Items.size)
237      acopy(this.a_Items, this.chosen)
238      this.listbox2.datasource := this.listbox2.datasource
239      this.available.size := 0
240      this.listbox1.datasource := this.listbox1.datasource
241      this.countItems()
242      this.listbox2.cursel := 1
243   endif
244   return
 

245  function onOpen
246    this.borderStyle := 3
247    if type("this.a_Items") # "A"
248      this.a_Items=new array()
249      For i = 1 to 9
250        this.a_Items.add("Item No. " + i)
251      Next
252    else
253      this.a_items.sort()
254    endif

255    this.available = new array( this.a_Items.size )
256    acopy( this.a_Items, this.available )
257    this.listbox1.datasource := 'array this.available'
258    this.listbox1.cursel := 1
259    this.chosen = new array()
260    this.listbox2.datasource := 'array this.chosen'
261    this.countItems()
262    this.visible := true
263    return

264  endclass

To return to the article   "A new Mover class"