add selectConditionBlock: to enable the selection of a row
authorca
Tue, 17 Feb 2004 14:11:46 +0100
changeset 2636 103067a67ff9
parent 2635 a8add4698dea
child 2637 d563163414b8
add selectConditionBlock: to enable the selection of a row
DSVColumnView.st
DataSetColumn.st
--- a/DSVColumnView.st	Tue Feb 17 13:09:19 2004 +0100
+++ b/DSVColumnView.st	Tue Feb 17 14:11:46 2004 +0100
@@ -31,7 +31,7 @@
 		dropSource columnAdaptor tabAtEndAction tabAtStartAction
 		modifiedChannel autoScroll autoScrollBlock needFitColumns
 		scrollWhenUpdating selectionForegroundColor
-		selectionBackgroundColor previousExtent'
+		selectionBackgroundColor previousExtent selectConditionBlock'
 	classVariableNames:'DefaultForegroundColor DefaultBackgroundColor
 		DefaultHilightForegroundColor DefaultHilightBackgroundColor
 		ButtonLightColor ButtonShadowColor CheckToggleActiveImage
@@ -392,6 +392,24 @@
 
 !
 
+selectConditionBlock
+    "get the select-conditionBlock; this block is evaluated before 
+     any selection change is performed (passing the to-be-changed row number
+     index as arg).
+     The change will not be done, if the block returns false. 
+    "
+    ^ selectConditionBlock
+!
+
+selectConditionBlock:aOneArgBlockOrNil
+    "set the select-conditionBlock; this block is evaluated before 
+     any selection change is performed (passing the to-be-changed row number
+     index as arg).
+     The change will not be done, if the block returns false. 
+    "
+    selectConditionBlock := aOneArgBlockOrNil.
+!
+
 tabAtEndAction:aNoneArgAction
     "set the action, called without any argument at end of the list entering
      tab next.
@@ -2080,6 +2098,8 @@
         ^ self
     ].
 
+    (self isRowSelectable:rowNr) ifFalse:[^ self ].
+
     sensor ctrlDown ifTrue:[
         self buttonControlPressAtRowNr:rowNr.
         ^ self
@@ -2304,27 +2324,45 @@
         or:[rawKey == #Home
         or:[rawKey == #End] 
     ]]) ifTrue:[
-        (hasSelectables or:[selectRowOnDefault]) ifTrue:[
+        (hasSelectables or:[selectRowOnDefault]) ifTrue:[ |step start|
             minSelRowNr := self minIndexSelected.
             maxSelRowNr := self maxIndexSelected.
 
             selColNr := hasSelectables ifFalse:[0]
                                         ifTrue:[selectedColIndex].
-        
+
             aKey == #CursorUp ifTrue:[
                 selRowNr := minSelRowNr > 1 ifTrue:[minSelRowNr - 1] ifFalse:[listSize].
+                step := -1.
             ] ifFalse:[
                 aKey == #CursorDown ifTrue:[
                     selRowNr := maxSelRowNr < listSize ifTrue:[maxSelRowNr + 1] ifFalse:[1].
+                    step := 1.
                 ] ifFalse:[
                     aKey == #BeginOfLine ifTrue:[
                         selRowNr := 1.
+                        step := 1.
                     ] ifFalse:[
                         selRowNr := listSize.
+                        step := -1.
                     ]
                 ]
             ].
-
+            start := selRowNr.
+
+            [ self isRowSelectable:selRowNr ] whileFalse:[
+                selRowNr := selRowNr + step.
+
+                selRowNr == 0 ifTrue:[
+                    selRowNr := listSize.
+                ] ifFalse:[
+                    selRowNr > listSize ifTrue:[
+                        selRowNr := 1.
+                    ].
+                ].
+                selRowNr == start ifTrue:[^ self ].
+            ].
+                                
             ((aKey == #CursorUp) or:[aKey == #CursorDown]) ifTrue:[
                 (multipleSelectOk and:[self sensor shiftDown]) ifTrue:[
                     self addRowToSelection:selRowNr.
@@ -2380,17 +2418,21 @@
 
         [true] whileTrue:[
             (selColNr := selColNr - 1) == 0 ifTrue:[
-                (selRowNr := selRowNr - 1) == 0 ifTrue:[
-                    isTab ifTrue:[
-                        tabAtStartAction notNil ifTrue:[
-                            tabAtStartAction value
-                        ] ifFalse:[
-                            self deselect.
-                            self windowGroup focusPreviousFrom:self
-                        ]
+                [   selRowNr := selRowNr - 1.
+                    selRowNr == 0 ifTrue:[
+                        isTab ifTrue:[
+                            tabAtStartAction notNil ifTrue:[
+                                tabAtStartAction value
+                            ] ifFalse:[
+                                self deselect.
+                                self windowGroup focusPreviousFrom:self
+                            ]
+                        ].
+                        ^ self
                     ].
-                    ^ self
-                ].
+                    (self isRowSelectable:selRowNr)
+                ] whileFalse.
+
                 selColNr := maxColNr
             ].
             column := self columnAt:selColNr.
@@ -2406,17 +2448,21 @@
 
     [true] whileTrue:[
         (selColNr := selColNr + 1) > maxColNr ifTrue:[
-            (selRowNr := selRowNr + 1) > listSize ifTrue:[
-                isTab ifTrue:[
-                    tabAtEndAction notNil ifTrue:[
-                        tabAtEndAction value
-                    ] ifFalse:[
-                        self deselect.
-                        self windowGroup focusNextFrom:self
-                    ]
+            [   selRowNr := selRowNr + 1.
+                selRowNr > listSize ifTrue:[
+                    isTab ifTrue:[
+                        tabAtEndAction notNil ifTrue:[
+                            tabAtEndAction value
+                        ] ifFalse:[
+                            self deselect.
+                            self windowGroup focusNextFrom:self
+                        ]
+                    ].
+                    ^ self
                 ].
-                ^ self
-            ].
+                (self isRowSelectable:selRowNr)
+            ] whileFalse.
+
             selColNr := 1
         ].
         column := self columnAt:selColNr.
@@ -2987,6 +3033,16 @@
     ^ enableChannel value ~~ false
 !
 
+isRowSelectable:aRowNumber
+    "returne true if a row number is selectable
+    "
+    (aRowNumber notNil and:[aRowNumber ~~ 0]) ifTrue:[
+        selectConditionBlock isNil ifTrue:[^ true].
+        ^ (selectConditionBlock value:aRowNumber)
+    ].
+    ^ false
+!
+
 numberOfColumns
     "returns number of columns
     "
@@ -3375,6 +3431,10 @@
     "
     |newSelection|
 
+    (self isRowSelectable:aRowNr) ifFalse:[
+        ^ self
+    ].
+
     self numberOfSelections == 0 ifTrue:[
         self selectColIndex:0 rowIndex:aRowNr.
         ^ self
@@ -3590,12 +3650,11 @@
 selectAllRows
     "select all
     "
-    selectedRowIndex isNil ifTrue:[selectedRowIndex := OrderedCollection new].
-    1 to:list size do:[:eachRowNr |
-        selectedRowIndex add:eachRowNr.    
-        self invalidateRowAt:eachRowNr.
-    ].
+    multipleSelectOk ifFalse:[^ self].
+
+    selectedRowIndex := (1 to:list size) select:[:idx| self isRowSelectable:idx ].
     self selectionChanged.
+    self invalidate.
 !
 
 selectColIndex:aColNr rowIndex:aRowNr
@@ -3645,7 +3704,7 @@
 
     step := (start <= stop) ifTrue:1 ifFalse:-1.
 
-    newSelection := (start to:stop by:step) asOrderedCollection.
+    newSelection := (start to:stop by:step) select:[:idx| self isRowSelectable: idx ].
 
     selectedColIndex ~~ 0 ifTrue:[
         self selectColIndex:0 rowIndex:newSelection.
@@ -3924,30 +3983,36 @@
         ^ multipleSelectOk ifFalse:[0] ifTrue:[nil]
     ].
 
-    newSel isNumber ifTrue:[
-        ^ multipleSelectOk ifFalse:[newSel] ifTrue:[OrderedCollection with:newSel]
+    multipleSelectOk ifFalse:[
+        newSel isNumber ifFalse:[
+            newSel := self identityIndexOfRow:aSelection.
+        ].
+        ^ (self isRowSelectable:newSel) ifTrue:[newSel] ifFalse:[0].
     ].
-    multipleSelectOk ifFalse:[
-        newSel := self identityIndexOfRow:aSelection
-    ] ifTrue:[
-        newSel := nil.
-
-        aSelection size ~~ 0 ifTrue:[
-            aSelection first isNumber ifTrue:[
-                newSel := aSelection
-            ] ifFalse:[
-                newSel := aSelection 
-                                collect:[:el | self identityIndexOfRow:el ]
-                                thenSelect:[:idx | idx ~~ 0].
-                newSel isEmpty ifTrue:[ newSel := nil ].
-            ]
-        ]
+
+    "multiple selection
+    "
+    aSelection size ~~ 0 ifTrue:[
+        aSelection first isNumber ifTrue:[
+            newSel := aSelection select:[:idx| self isRowSelectable:idx ].
+        ] ifFalse:[
+            newSel := aSelection 
+                            collect:[:el| self identityIndexOfRow:el ]
+                            thenSelect:[:idx| self isRowSelectable:idx ].
+        ].
+        newSel notEmpty ifTrue:[
+            ^ newSel
+        ].
+    ] ifFalse:[
+        (newSel isNumber and:[self isRowSelectable:newSel]) ifTrue:[
+            ^ Array with:newSel
+        ].
     ].
-    ^ newSel
+    ^ nil
 ! !
 
 !DSVColumnView class methodsFor:'documentation'!
 
 version
-    ^ '$Header: /cvs/stx/stx/libwidg2/DSVColumnView.st,v 1.177 2003-12-17 12:30:08 ca Exp $'
+    ^ '$Header: /cvs/stx/stx/libwidg2/DSVColumnView.st,v 1.178 2004-02-17 13:10:51 ca Exp $'
 ! !
--- a/DataSetColumn.st	Tue Feb 17 13:09:19 2004 +0100
+++ b/DataSetColumn.st	Tue Feb 17 14:11:46 2004 +0100
@@ -1066,23 +1066,25 @@
         char  := aChar asLowercase.
 
         start to:stop do:[:eachNr| |row lbl|
-            row := dataSet at:eachNr.
-            lbl := self shownValueForRow:row rowNr:eachNr.
+            (dataSet isRowSelectable:eachNr) ifTrue:[
+                row := dataSet at:eachNr.
+                lbl := self shownValueForRow:row rowNr:eachNr.
 
-            (lbl isSequenceable and:[lbl isString not]) ifTrue:[
-                lbl := lbl at:1 ifAbsent:nil
-            ].
+                (lbl isSequenceable and:[lbl isString not]) ifTrue:[
+                    lbl := lbl at:1 ifAbsent:nil
+                ].
 
-            (lbl respondsTo:#string) ifTrue:[
-                lbl := lbl string.
-                (lbl size ~~ 0 and:[(lbl at:1) asLowercase == char]) ifTrue:[
-                    ^ eachNr
-                ]
-            ] ifFalse:[
-                lbl isNil ifFalse:[
-                    ^ 0
-                ]
-            ]
+                (lbl respondsTo:#string) ifTrue:[
+                    lbl := lbl string.
+                    (lbl size ~~ 0 and:[(lbl at:1) asLowercase == char]) ifTrue:[
+                        ^ eachNr
+                    ]
+                ] ifFalse:[
+                    lbl isNil ifFalse:[
+                        ^ 0
+                    ].
+                ].
+            ].
         ]
     ].
     ^ 0
@@ -1091,5 +1093,5 @@
 !DataSetColumn class methodsFor:'documentation'!
 
 version
-    ^ '$Header: /cvs/stx/stx/libwidg2/DataSetColumn.st,v 1.92 2004-02-17 12:09:19 cg Exp $'
+    ^ '$Header: /cvs/stx/stx/libwidg2/DataSetColumn.st,v 1.93 2004-02-17 13:11:46 ca Exp $'
 ! !