TypeConverter.st
changeset 2613 4c6bedf19f55
parent 2607 2f81fde8732a
child 2620 7bd45a3ea825
--- a/TypeConverter.st	Wed Mar 11 01:50:55 2009 +0100
+++ b/TypeConverter.st	Sun Mar 15 05:12:03 2009 +0100
@@ -128,6 +128,41 @@
             Transcript showCR:v value
         ]
                                                                         [exEnd]
+    convert with scale character:
+                                                                        [exBegin]
+        |d v|
+
+        v := 1234567 asValue.
+
+        d := DialogBox new.
+        d addInputFieldOn:((TypeConverter on:v) numberWithOptionalScale).
+        d addOkButton.
+        d open.
+        d accepted ifTrue:[
+            Transcript showCR:v value
+        ]
+                                                                        [exEnd]
+    convert with scale character and thousands separator:
+                                                                        [exBegin]
+        |d v scaleDict|
+
+        scaleDict := Dictionary new.
+        scaleDict at:$t put:1000.
+        scaleDict at:$k put:1000.
+        scaleDict at:$m put:1000000.
+
+        v := 1234567 asValue.
+
+        d := DialogBox new.
+        d addInputFieldOn:((TypeConverter on:v) 
+                            numberWithOptionalScales:scaleDict 
+                            andThousandsSeparator:$').
+        d addOkButton.
+        d open.
+        d accepted ifTrue:[
+            Transcript showCR:v value
+        ]
+                                                                        [exEnd]
 "
 ! !
 
@@ -740,38 +775,14 @@
 !
 
 integerWithThousandsSeparator    
-    ^ self integerWithThousandsSeparator:$'
-"/     ^ self integerWithThousandsSeparator:(UserPreferences current thousandsSeparatorCharacter)
+    ^ self numberWithThousandsSeparator
 !
 
 integerWithThousandsSeparator:sep
     "setup the converter to convert from a string to a number with thousands separator
      and vice versa."
 
-    self
-        getBlock:[:model |
-                |numericValue|
-
-                (numericValue := model value) isNumber ifFalse:[
-                    String new
-                ] ifTrue:[
-                    String streamContents:[:s | numericValue printOn:s thousandsSeparator:sep].
-                ]]
-
-        putBlock:
-                [:model :string |
-
-                |value s2|
-
-                string isEmptyOrNil ifTrue:[
-                    value := 0
-                ] ifFalse:[
-                    s2 := string reject:[:ch | ch = sep].    
-                    value := Number readFromString:s2 onError:[0]
-                ].
-                model value:value]
-
-        updateBlock: [:m :a :p | true]
+    ^ self numberWithThousandsSeparator:sep
 !
 
 literal
@@ -1214,6 +1225,133 @@
     "Modified: 21.2.1997 / 18:59:44 / cg"
 !
 
+numberWithOptionalScale
+    "setup the converter to convert from a string to a number
+     and vice versa. Invalid numbers are converted to nil.
+     The number may be followed by one of m (for million) or
+     k (for thousand)"
+
+    |scaleDict|
+
+    scaleDict := Dictionary new.
+    scaleDict at:$m put:1000000.
+    scaleDict at:$k put:1000.
+    self numberWithOptionalScales:scaleDict
+!
+
+numberWithOptionalScales:scaleDict
+    "setup the converter to convert from a string to a number or nil
+     and vice versa; allow for scale characters (such as k for thousand)"
+
+    self
+        getBlock:[:model |
+                    |numericValue|
+
+                    (numericValue := model value) isNil ifTrue:[
+                        String new
+                    ] ifFalse:[
+                        numericValue printString
+                    ]
+                ]
+
+        putBlock:
+                [:model :string |
+
+                    |value c stream scaleChar scale|
+
+                    (string isEmptyOrNil or:[string isBlank]) ifTrue:[
+                        value := nil
+                    ] ifFalse:[
+                        stream := string readStream.
+                        value := Number readFrom:stream onError:[nil]. 
+                        value notNil ifTrue:[
+                            stream skipSeparators.
+                            scaleChar := stream peek.
+                            scale := scaleDict at:scaleChar ifAbsent:1.
+                            value := value * scale.
+                        ].
+                    ].
+                    self setNumberValue: value inModel: model fromInput: string.
+                ]
+
+        updateBlock: [:m :a :p | true]
+!
+
+numberWithOptionalScales:scaleDict andThousandsSeparator:sep
+    "setup the converter to convert from a string to a number with thousands separator
+     and vice versa. Allow for scale characters (such as k for thousand) "
+
+    self
+        getBlock:[:model |
+                    |numericValue|
+
+                    (numericValue := model value) isNumber ifFalse:[
+                        String new
+                    ] ifTrue:[
+                        String streamContents:[:s | numericValue printOn:s thousandsSeparator:sep].
+                    ]
+                ]
+
+        putBlock:
+                [:model :string |
+
+                    |value c stream scaleChar scale s2|
+
+                    string isEmptyOrNil ifTrue:[
+                        value := 0
+                    ] ifFalse:[
+                        s2 := string reject:[:ch | ch = sep].    
+                        stream := s2 readStream.
+                        value := Number readFrom:stream onError:[nil]. 
+                        value notNil ifTrue:[
+                            stream skipSeparators.
+                            scaleChar := stream peek.
+                            scale := scaleDict at:scaleChar ifAbsent:1.
+                            value := value * scale.
+                        ].
+                    ].
+                    "/ model value:value
+                    self setNumberValue: value inModel: model fromInput: string.
+                ]
+
+        updateBlock: [:m :a :p | true]
+!
+
+numberWithThousandsSeparator    
+    ^ self numberWithThousandsSeparator:$'
+"/     ^ self numberWithThousandsSeparator:(UserPreferences current thousandsSeparatorCharacter)
+!
+
+numberWithThousandsSeparator:sep
+    "setup the converter to convert from a string to a number with thousands separator
+     and vice versa."
+
+    self
+        getBlock:[:model |
+                |numericValue|
+
+                (numericValue := model value) isNumber ifFalse:[
+                    String new
+                ] ifTrue:[
+                    String streamContents:[:s | numericValue printOn:s thousandsSeparator:sep].
+                ]]
+
+        putBlock:
+                [:model :string |
+
+                |value s2|
+
+                string isEmptyOrNil ifTrue:[
+                    value := 0
+                ] ifFalse:[
+                    s2 := string reject:[:ch | ch = sep].    
+                    value := Number readFromString:s2 onError:[0]
+                ].
+                model value:value]
+
+        updateBlock: [:m :a :p | true]
+!
+
 objectOrNilOfType:timeOrDateClass
     "common code for timeOrNil, dateOrNil and timeStampOrNil"
 
@@ -1575,5 +1713,5 @@
 !TypeConverter class methodsFor:'documentation'!
 
 version
-    ^ '$Header: /cvs/stx/stx/libview2/TypeConverter.st,v 1.58 2009-03-05 20:34:28 cg Exp $'
+    ^ '$Header: /cvs/stx/stx/libview2/TypeConverter.st,v 1.59 2009-03-15 04:12:03 cg Exp $'
 ! !