'****************************************************************************
'* Copyright (C) 2004 Peter Mortensen and Matthias Mann *
'* This file is part of MSQuant. *
'* *
'* MSQuant is distributed under the terms of *
'* the GNU General Public License. See src/COPYING.TXT or *
'* <http://www.gnu.org/licenses/gpl.txt> for details. *
'* *
'* MSQuant is free software; you can redistribute it *
'* and/or modify it under the terms of the GNU *
'* General Public License as published by the Free *
'* Software Foundation; either version 2 of the *
'* License, or (at your option) any later version. *
'* *
'* MSQuant is distributed in the hope that it will be *
'* useful, but WITHOUT ANY WARRANTY; without even the *
'* implied warranty of MERCHANTABILITY or FITNESS FOR *
'* A PARTICULAR PURPOSE. See the GNU General Public *
'* License for more details. *
'* *
'* You should have received a copy of the GNU General *
'* Public License along with MSQuant; if not, write to *
'* the Free Software Foundation, Inc., 59 Temple *
'* Place, Suite 330, Boston, MA 02111-1307 USA *
'* *
'* Purpose: provides sort class to be used to sort a ListView - by *
'* setting the property ListViewItemSorter to instance of *
'* this class. Clients specify a logical column, actual column *
'* is determined by an instance of a listviewColumnMapper. *
'* Clients can specify secondary columns/keys for the sort and *
'* specify datatype and direction (ascending/descending) for each *
'* key *
'* *
'****************************************************************************
'****************************************************************************
'* CEBI *
'* Software Development Group *
'* Peter Mortensen *
'* E-mail: NUKESPAMMERSdrmortensen@get2netZZZZZZ.dk *
'* WWW: http://www.cebi.sdu.dk/ *
'* *
'* Program for post-processing of result from search in mass *
'* spectrometric data. *
'* *
'* FILENAME: listviewColumnMapper.vb *
'* TYPE: VISUAL_BASIC *
'* *
'* CREATED: PM 2006-02-23 Vrs 1.0. *
'* UPDATED: PM 2005-xx-xx *
'* *
'****************************************************************************
'Future:
' 1. What if the column for a key does not exist in the current ListViewItem?
Option Strict On
Option Explicit On
'****************************************************************************
'* <placeholder for header> *
'****************************************************************************
Namespace CEBI_generalGUI 'Better name? Things in this name space are
' application independent stuff (bug fixes, extensions,
' generalisations) that could be used elsewhere. It is
' not even mass spec specific.
Public Enum sortingDirectionEnum
enumAscendingSort = 293
enumDescendingSort
End Enum 'sortingDirectionEnum
Public Enum datatypeEnum
enumText = 293
enumInteger
enumDecimalNumber
End Enum 'sortingDirectionEnum
Public Structure sortKeyStructure
Dim columnID As Integer
Dim physicalColumn As Integer 'Helper field. For caching.
' Value derived from columnID.
Dim sortDirection As sortingDirectionEnum
Dim dataType As datatypeEnum
'For convenience initialisation.
Public Sub New( _
ByRef aColumnID As Integer, _
ByVal aDataType As datatypeEnum, _
ByVal aSortDirection As sortingDirectionEnum)
columnID = aColumnID
dataType = aDataType
sortDirection = aSortDirection
End Sub 'New
End Structure 'sortKeyStructure
'****************************************************************************
'* <placeholder for header> *
'****************************************************************************
Public Class ListViewColumnSorter
Implements IComparer
Private mColumnMapper As listviewColumnMapper
Private mCurrentKeyList As ArrayList
'****************************************************************************
'* SUBROUTINE NAME: New *
'd$ <summary>Constructor</summary>
Public Sub New(ByRef anInColumnMapper As listviewColumnMapper)
MyBase.New() 'Is this necessary? Yes!
Trace.Assert(Not anInColumnMapper Is Nothing, _
"PIL ASSERT. anInColumnMapper is Nothing.")
mColumnMapper = anInColumnMapper
End Sub 'New()
'****************************************************************************
'* <placeholder for header> *
'****************************************************************************
Public Sub prepareSort( _
ByVal aKeylist2 As Generic.List(Of sortKeyStructure))
'Old:
' ByVal aKeylist As ArrayList
' Item type of aKeylist is: sortKeyStructure
'Cache the physical column number in the datastructure. Done here
'during a deep copy of the input list.
mCurrentKeyList = New ArrayList
Dim someKey As sortKeyStructure
For Each someKey In aKeylist2
Dim copiedKey As sortKeyStructure = someKey
copiedKey.physicalColumn = _
mColumnMapper.item2ColumnIndex(copiedKey.columnID)
mCurrentKeyList.Add(copiedKey)
Next
End Sub 'prepareSort
'****************************************************************************
'* <placeholder for header> *
'****************************************************************************
Private Function Compare(ByVal x As Object, ByVal y As Object) As Integer _
Implements System.Collections.IComparer.Compare
Dim item1 As ListViewItem = CType(x, ListViewItem)
Dim item2 As ListViewItem = CType(y, ListViewItem)
Dim toReturn As Integer = 0 'In case
Dim someKey As sortKeyStructure
For Each someKey In mCurrentKeyList
Dim physCol As Integer = someKey.physicalColumn
'Under normal circumstances these two
'indices are always the same as all rows have
'the same number of columns. But it can
'happen that sorting is used during building
'up of the list (by a screen update?) and
'then a partly completed row can be compared
'against a full row.
Dim lastIndex1 As Integer = item1.SubItems.Count() - 1
Dim lastIndex2 As Integer = item2.SubItems.Count() - 1
Trace.Assert(physCol <= lastIndex1, _
"Index, " & physCol & ", is past last index in item1.SubItems, " & _
lastIndex1 & ".")
Trace.Assert(physCol <= lastIndex2, _
"Index, " & physCol & ", is past last index in item1.SubItems, " & _
lastIndex2 & ".")
Dim str1 As String = item1.SubItems(physCol).Text
Dim str2 As String = item2.SubItems(physCol).Text
If str1 = "..." Then
'Changed PM_QUANTCOLUMNS_SORT 2007-04-03
'str1 = "0"
str1 = "-1e-20"
End If
If str2 = "..." Then
'Changed PM_QUANTCOLUMNS_SORT 2007-04-03
'str2 = "0"
str2 = "-1e-20"
End If
'Changed PM_QUANTCOLUMNS_SORT 2007-04-03
If str1 = "NaN" Then
str1 = "-1e-22"
End If
If str2 = "NaN" Then
str2 = "-1e-22"
End If
'Dim compareResult As Integer = 0
Select Case someKey.dataType
Case datatypeEnum.enumText
'Initially ascending, but we reverse the result later
'if descending is specified.
If str1 > str2 Then
toReturn = 1
Else
If str1 < str2 Then
toReturn = -1
Else
'Equal...
Dim peter1 As Integer = 1
End If
End If
Case datatypeEnum.enumInteger
Dim int1 As Integer = CInt(str1)
Dim int2 As Integer = CInt(str2)
'Initially ascending, but we reverse the result later
'if descending is specified.
If int1 > int2 Then
toReturn = 1
Else
If int1 < int2 Then
toReturn = -1
Else
'Equal...
Dim peter1 As Integer = 1
End If
End If
Case datatypeEnum.enumDecimalNumber
'Ignore any parenthesises around the number, e.g.: (47)
Dim startIndex1 As Integer = str1.IndexOf("(")
If startIndex1 >= 0 Then
Dim endIndex1 As Integer = str1.IndexOf(")")
If endIndex1 >= 0 Then
startIndex1 += 1 'Step over "("
Dim len1 As Integer = endIndex1 - startIndex1
str1 = str1.Substring(startIndex1, len1)
End If
End If
Dim startIndex2 As Integer = str2.IndexOf("(")
If startIndex2 >= 0 Then
Dim endIndex2 As Integer = str2.IndexOf(")")
If endIndex2 >= 0 Then
startIndex2 += 1 'Step over "("
Dim len2 As Integer = endIndex2 - startIndex2
str2 = str2.Substring(startIndex2, len2)
End If
End If
Dim d1 As Double = CDbl(str1)
Dim d2 As Double = CDbl(str2)
'Initially ascending, but we reverse the result later
'if descending is specified.
If d1 > d2 Then
toReturn = 1
Else
If d1 < d2 Then
toReturn = -1
Else
'Equal...
Dim peter1 As Integer = 1
End If
End If
Case Else
Trace.Assert(False, "PIL ASSERT. Select Case never fall-through")
End Select
If someKey.sortDirection = sortingDirectionEnum.enumDescendingSort Then
toReturn = -toReturn
End If
If toReturn = 0 Then
'The two keys are equal. We must go to a lower
'level key (if there are any) - by continuing the loop.
Dim peter1 As Integer = 1
Else
Exit For 'Two current keys are not equal. We need not
'compare more keys. Stop.
End If
Next
Return toReturn
End Function 'Compare
End Class 'ListViewColumnSorter
End Namespace 'CEBI_generalGUI
Generated by script codePublish.pl at 2008-09-23T11:59:18.