MultiColListEntry.st
changeset 58 2bdd35f8aef0
parent 36 160b8f0dfd7d
child 62 378b60ba1200
--- a/MultiColListEntry.st	Fri May 12 20:40:42 1995 +0200
+++ b/MultiColListEntry.st	Wed May 17 14:49:25 1995 +0200
@@ -10,7 +10,9 @@
  hereby transferred.
 "
 
-Object subclass:#MultiColListEntry
+'From Smalltalk/X, Version:2.10.5 on 15-may-1995 at 9:15:44 am'!
+
+ListEntry subclass:#MultiColListEntry
 	 instanceVariableNames:'strings tabSpec'
 	 classVariableNames:''
 	 poolDictionaries:''
@@ -35,7 +37,7 @@
 
 version
 "
-$Header: /cvs/stx/stx/libwidg2/MultiColListEntry.st,v 1.4 1995-02-17 13:23:47 claus Exp $
+$Header: /cvs/stx/stx/libwidg2/MultiColListEntry.st,v 1.5 1995-05-17 12:49:05 claus Exp $
 "
 !
 
@@ -58,198 +60,225 @@
 
 examples
 "
-     'putting multiColListEntries into a ListView
-      (instead of strings)'
+     putting multiColListEntries into a ListView
+     (instead of strings)'
+        
+	|v e myList tabs|
 
-     |v e myList tabs|
+	myList := OrderedCollection new.
 
-     myList := OrderedCollection new.
+	tabs := TabulatorSpecification new.
+	tabs unit:#inch.
+	tabs positions:#(0 3 4).
+	tabs align:#(left #center #left).
 
-     tabs := TabulatorSpecification new.
-     tabs unit:#inch.
-     tabs positions:#(0 3 6).
-     tabs align:#(left #left #left).
+	e := MultiColListEntry 
+		 fromString:'left centered left'.
+	e tabulatorSpecification:tabs.
+	myList add:e.
+
+	e := MultiColListEntry 
+		 fromString:'| | |'.
+	e tabulatorSpecification:tabs.
+	myList add:e.
+	myList add:''.
 
-     e := MultiColListEntry new.
-     e colAt:1 put:'hello'.
-     e colAt:2 put:'hallo'.
-     e colAt:3 put:'salut'.
-     e tabulatorSpecification:tabs.
-     myList add:e.
+	e := MultiColListEntry 
+		 fromString:'hello hallo salut'.
+	e tabulatorSpecification:tabs.
+	myList add:e.
+
+	e := MultiColListEntry 
+		 fromString:'good morning,guten Morgen,bon jour'
+		 separatedBy:$,.
+	e tabulatorSpecification:tabs.
+	myList add:e.
 
-     e := MultiColListEntry new.
-     e colAt:1 put:'good morning'.
-     e colAt:2 put:'guten Morgen'.
-     e colAt:3 put:'bon jour'.
-     e tabulatorSpecification:tabs.
-     myList add:e.
+	e := MultiColListEntry new.
+	e colAt:1 put:'good bye'.
+	e colAt:2 put:'auf Wiedersehen'.
+	e colAt:3 put:'au revoir '.
+	e tabulatorSpecification:tabs.
+	myList add:e.
 
-     e := MultiColListEntry new.
-     e colAt:1 put:'good bye'.
-     e colAt:2 put:'auf Wiedersehen'.
-     e colAt:3 put:'au revoir '.
-     e tabulatorSpecification:tabs.
-     myList add:e.
-
-     v := ListView new.
-     v setList:myList expandTabs:false.
-     v open
+	v := ListView new.
+	v setList:myList expandTabs:false.
+	v extent:500@100.
+	v open
 
 
 
-     'many multiColListEntries in a scrollable ListView'
+     many multiColListEntries in a scrollable ListView
 
-     |v e myList tabs|
+	|v l e myList tabs|
 
-     myList := OrderedCollection new.
+	myList := OrderedCollection new.
 
-     tabs := TabulatorSpecification new.
-     tabs unit:#cm.
-     tabs positions:#(1 3 5).
-     tabs align:#(#right #center #left).
+	tabs := TabulatorSpecification new.
+	tabs unit:#cm.
+	tabs positions:#(1 3 5).
+	tabs align:#(#right #center #left).
 
-     1 to:100 do:[:i|
-	 e := MultiColListEntry new.
-	 e colAt:1 put:i printString.
-	 e colAt:2 put:i squared printString.
-	 e colAt:3 put:i sqrt  printString.
-	 e tabulatorSpecification:tabs.
-	 myList add:e.
-     ].
-     v := ScrollableView for:ListView.
-     v setList:myList expandTabs:false.
-     v open
+	1 to:100 do:[:i|
+	    e := MultiColListEntry new.
+	    e colAt:1 put:i printString.
+	    e colAt:2 put:i squared printString.
+	    e colAt:3 put:i sqrt  printString.
+	    e tabulatorSpecification:tabs.
+	    myList add:e.
+	].
+	l := ListView new.
+	l setList:myList expandTabs:false.
+	v := ScrollableView forView:l.
+	v extent:300@200.
+	v open
 
 
 
-     'like above, but adds nice alignments'
+     like above, but uses nicer decimal alignments
 
-     |v e myList tabs|
+	|v l e myList tabs|
 
-     myList := OrderedCollection new.
-
-     tabs := TabulatorSpecification new.
-     tabs unit:#cm.
-     tabs positions:#(1 3 6 9 12).
-     tabs align:#(#right #decimal #decimal #decimal #decimal).
+	myList := OrderedCollection new.
+        
+	tabs := TabulatorSpecification new.
+	tabs unit:#cm.
+	tabs positions:#(1 3 6 9 12).
+	tabs align:#(#right #decimal #decimal #decimal #decimal).
 
-     1 to:100 do:[:i|
-	 e := MultiColListEntry new.
-	 e colAt:1 put:i printString.
-	 e colAt:2 put:i log printString.
-	 e colAt:3 put:i sqrt  printString.
-	 e colAt:4 put:i sin  printString.
-	 e colAt:5 put:i cos  printString.
-	 e tabulatorSpecification:tabs.
-	 myList add:e.
-     ].
-     v := ScrollableView for:ListView.
-     v setList:myList expandTabs:false.
-     v open
+	1 to:100 do:[:i|
+	    e := MultiColListEntry new.
+	    e colAt:1 put:i printString.
+	    e colAt:2 put:i log printString.
+	    e colAt:3 put:i sqrt  printString.
+	    e colAt:4 put:i sin  printString.
+	    e colAt:5 put:i cos  printString.
+	    e tabulatorSpecification:tabs.
+	    myList add:e.
+	].
+	l := ListView new.
+	l setList:myList expandTabs:false.
+	v := ScrollableView forView:l.
+	v extent:600@200.
+	v open
 
 
 
-     'specifying tabs in inches'
+     specifying tabs in inches
 
-     |v e myList tabs|
+	|v l e myList tabs|
 
-     myList := OrderedCollection new.
+	myList := OrderedCollection new.
 
-     tabs := TabulatorSpecification new.
-     tabs unit:#inch.
-     tabs positions:#(0 2 3.5 4 6 8 10 12).
+	tabs := TabulatorSpecification new.
+	tabs unit:#inch.
+	tabs positions:#(0 2 3.5 4 6 8 10 12).
 
-     e := MultiColListEntry new.
-     e colAt:1 put:'2'.
-     e colAt:2 put:'3.5'.
-     e colAt:3 put:'4'.
-     e colAt:4 put:'6'.
-     e colAt:5 put:'8'.
-     e colAt:6 put:'10'.
-     e colAt:7 put:'12'.
-     e tabulatorSpecification:tabs.
-     myList add:e.
+	e := MultiColListEntry new.
+	e colAt:1 put:'2'.
+	e colAt:2 put:'3.5'.
+	e colAt:3 put:'4'.
+	e colAt:4 put:'6'.
+	e colAt:5 put:'8'.
+	e colAt:6 put:'10'.
+	e colAt:7 put:'12'.
+	e tabulatorSpecification:tabs.
+	myList add:e.
 
-     v := ScrollableView for:ListView.
-     v setList:myList expandTabs:false.
-     v open
+	myList add:((MultiColListEntry fromString:'| | | | | | |')
+			 tabulatorSpecification:tabs).
+	myList add:((MultiColListEntry fromString:'xxx xxx xxx xxx xxx xxx xxx')
+			 tabulatorSpecification:tabs).
+
+	l := ListView new.
+	l setList:myList expandTabs:false.
+	v := HVScrollableView forView:l.
+	v extent:600@200.
+	v open
 
 
-     'if you have the columns available as a collection, 
-      setup can be done easier'
+     if you have the columns available as a collection, 
+     setup can be done easier
+
+	|v l e myList tabs|
+
+	myList := OrderedCollection new.
+
+	tabs := TabulatorSpecification new.
+	tabs unit:#inch.
+	tabs positions:#(0 2 3.5 4 6 8 10 12).
+
+	e := MultiColListEntry new.
+	e strings:#('2' '3.5' '4' '6' '8' '10' '12').
+	e tabulatorSpecification:tabs.
+	myList add:e.
 
-     |v e myList tabs|
+	l := ListView new.
+	l setList:myList expandTabs:false.
+	v := HVScrollableView forView:l.
+	v extent:600@200.
+	v open
+
 
-     myList := OrderedCollection new.
+    concrete example, show /etc/passwd in a table:
+        
+	|v l s myList line e htabs tabs fingerEntry|
+
+	tabs := TabulatorSpecification new.
+	tabs unit:#inch.
+	tabs positions:#(0    2      3.5  4.5   5    8    11).
+	tabs align:    #(left left right right left left left).
 
-     tabs := TabulatorSpecification new.
-     tabs unit:#inch.
-     tabs positions:#(0 2 3.5 4 6 8 10 12).
+	htabs := TabulatorSpecification new.
+	htabs unit:#inch.
+	htabs positions:#(0    2      3.5      4.5    5    8    11).
+	htabs align:    #(left center center center left left left).
+
+	myList := OrderedCollection new.
+
+	e := MultiColListEntry 
+		    fromString:'login-name:password:uid:gid:finger-entry:home-dir:shell' 
+		    separatedBy:$:.
+	e tabulatorSpecification:htabs.
+	myList add:e.
+	myList add:''.
 
-     e := MultiColListEntry new.
-     e strings:#('2' '3.5' '4' '6' '8' '10' '12').
-     e tabulatorSpecification:tabs.
-     myList add:e.
-
-     v := ScrollableView for:ListView.
-     v setList:myList expandTabs:false.
-     v open
+	s := '/etc/passwd' asFilename readStream.
+	[s atEnd] whileFalse:[
+	    line := s nextLine.
+	    e := MultiColListEntry 
+			fromString:line
+			separatedBy:$:.
+	    fingerEntry := e colAt:5.
+	    e colAt:5 put:(fingerEntry asCollectionOfSubstringsSeparatedBy:$,) first.
+	    e tabulatorSpecification:tabs.
+	    myList add:e.
+	].
+	s close.
+        
+	l := ListView new.
+	l setList:myList expandTabs:false.
+	v := HVScrollableView forView:l.
+	v extent:600@200.
+	v open
 "
 ! !
 
-!MultiColListEntry methodsFor:'accessing'!
-
-strings:aCollectionOfStrings
-    "replace all substrings"
-
-    strings := OrderedCollection withAll:aCollectionOfStrings. 
-!
-
-colAt:index
-    "return the substring at column index"
+!MultiColListEntry class methodsFor:'instance creation'!
 
-    index > strings size ifTrue:[^ nil].
-    ^ strings at:index
-!
-
-colAt:index put:aString
-    "replace the substring at column index"
-
-    strings isNil ifTrue:[
-	strings := OrderedCollection new:index
-    ].
-    strings grow:index.
-    strings at:index put:aString
+fromString:aString
+    ^ self fromString:aString separatedBy:Character space
 !
 
-tabulatorSpecification:aTabSpec
-    "set the tabulator spec"
-
-    tabSpec := aTabSpec
-! !
-
-!MultiColListEntry methodsFor:'converting'!
-
-asString
-    "return the receiver as a string with embedded tabs"
-
-    |s sub tab 
-     nSub "{ Class: SmallInteger }"|
+fromString:aString separatedBy:separatorCharacter
+     |subStrings e|
 
-    s := ''.
-    tab := Character tab asString.
-    nSub := strings size.
-    1 to:nSub do:[:subStringIndex |
-	sub := strings at:subStringIndex.
-	sub notNil ifTrue:[
-	    s := s , sub.
-	].
-	subStringIndex == strings size ifFalse:[
-	    s := s , tab
-	]
+    e := self new.
+    subStrings := aString asCollectionOfSubstringsSeparatedBy:separatorCharacter.
+    subStrings keysAndValuesDo:[:i :sub |
+	e colAt:i put:sub.
     ].
-
-    ^ s
+    ^ e
 ! !
 
 !MultiColListEntry methodsFor:'drawing'!
@@ -279,6 +308,94 @@
 	    prevString := subString.
 	]
     ].
+! !
 
+!MultiColListEntry methodsFor:'accessing'!
+
+colAt:index put:aString
+    "replace the substring at column index"
+
+    strings isNil ifTrue:[
+	strings := OrderedCollection new:index
+    ].
+    index > strings size ifTrue:[strings grow:index].
+    strings at:index put:aString
+!
+
+tabulatorSpecification:aTabSpec
+    "set the tabulator spec"
+
+    tabSpec := aTabSpec
+!
+
+strings:aCollectionOfStrings
+    "replace all substrings"
+
+    strings := OrderedCollection withAll:aCollectionOfStrings. 
+!
+
+colAt:index
+    "return the substring at column index"
+
+    index > strings size ifTrue:[^ nil].
+    ^ strings at:index
 ! !
 
+!MultiColListEntry methodsFor:'queries'!
+
+widthIn:aGC
+    "return the width of the receiver when displayed in aGC"
+
+    |xPos xMax subString tabPos w prevLen|
+
+    "just to make certain:
+     do not assume, that the last col is the rightmost one ...
+    "
+    xPos := 0.
+    xMax := 0.
+    prevLen := 0.
+    strings keysAndValuesDo:[:index :subString |
+	subString notNil ifTrue:[
+	    "
+	     find next tab
+	    "
+	    tabPos := tabSpec positionOfTab:index forString:subString on:aGC.
+	    tabPos isNil ifTrue:[
+		"
+		 no tab - just continue where we are ...
+		"
+		xPos := xPos + prevLen.
+	    ] ifFalse:[
+		xPos := tabPos.
+	    ].
+	    w := prevLen := aGC font widthOf:subString.
+	    xMax := xMax max:(xPos + w).
+	]
+    ].
+    ^ xMax
+! !
+
+!MultiColListEntry methodsFor:'converting'!
+
+asString
+    "return the receiver as a string with embedded tabs"
+
+    |s sub tab 
+     nSub "{ Class: SmallInteger }"|
+
+    s := ''.
+    tab := Character tab asString.
+    nSub := strings size.
+    1 to:nSub do:[:subStringIndex |
+	sub := strings at:subStringIndex.
+	sub notNil ifTrue:[
+	    s := s , sub.
+	].
+	subStringIndex == strings size ifFalse:[
+	    s := s , tab
+	]
+    ].
+
+    ^ s
+! !
+