Omnis Technical Note TNGI0020 December 2007
Manually changing the sort order of list lines
For Omnis Studio 3/4
By Andreas Pfeiffer
In an application, you may want to allow end users to change the sort order of lines in a list by hand - normally a list is sorted according to one of the columns in the underlying list and the user may be able to select the column to sort the list. However, you can allow users to select individual or multiple list lines and reorder the list by dragging and dropping the list lines.
For this you can use a Headed List Box. To make sure the user can select multiple lines in the list you should set the property $multipleselect in the "Action" group to kTrue.
To activate drag & drop
In order to make the Headed List Box accept drag & drop you have to activate the properties $dragmode and $dropmode in the "Action" group. Set the property $dragmode to kDragData and the property $dropmode to kAcceptList so that the data can be dragged onto itself. In addition, you should set the property $dropbetweenlines to kTrue so that the selected lines can be dropped between other lines - to do this you need to set the property $highliteline to kTrue, otherwise the $dropbetweenlines property cannot be changed.
Prevent other objects from dropping onto this Headed List Box
You can ensure that other data from other objects cannot be dragged onto the Headed List Box by adding the following method to the $event method of the list:
; only drag and drop to reorder fields allowed
Quit event handler (Discard event)
And now changing the sorting order
To change the order of the list lines, you have to code the evDrop in the $event method for the list. You can use the pDragData event parameter which contains the contents of the "dragged" data:
; rearrange the line order
Calculate lineNumber as mouseover(kMLine)
; set the first selected line to be current
Do pDragValue.$addbefore(lineNumber) Returns lineRef
; adds an empty line before the dropped line number
Calculate pDragValue.$line as pDragValue.$line+1
; assign the data from the current row to the new empty line
Calculate lineNumber as lineNumber+1
; make the next selected line current
; delete the original data
Do $cinst.$redraw() ;. redraw the list
The method uses a local Integer variable which uses the mouseover(kMLine) function to detect the line number on which the user has dropped. Note that you cannot set a breakpoint before the mouseover() function, since you are using the mouse while debugging and so at that point the kMLine parameter will not return the required value.