SelListV.st
changeset 125 3ffa271732f7
parent 124 7abd3a234296
child 128 06a050529335
equal deleted inserted replaced
124:7abd3a234296 125:3ffa271732f7
     8  be provided or otherwise made available to, or used by, any
     8  be provided or otherwise made available to, or used by, any
     9  other person.  No title to or ownership of the software is
     9  other person.  No title to or ownership of the software is
    10  hereby transferred.
    10  hereby transferred.
    11 "
    11 "
    12 
    12 
    13 'From Smalltalk/X, Version:2.10.5 on 14-mar-1995 at 11:01:02 am'!
    13 'From Smalltalk/X, Version:2.10.5 on 8-may-1995 at 11:59:03 am'!
    14 
    14 
    15 ListView subclass:#SelectionInListView
    15 ListView subclass:#SelectionInListView
    16 	 instanceVariableNames:'selection actionBlock enabled hilightFgColor hilightBgColor
    16 	 instanceVariableNames:'selection actionBlock enabled hilightFgColor hilightBgColor
    17 		halfIntensityFgColor doubleClickActionBlock selectConditionBlock
    17                 halfIntensityFgColor doubleClickActionBlock selectConditionBlock
    18 		listAttributes multipleSelectOk clickLine initialSelectionMsg
    18                 listAttributes multipleSelectOk clickLine initialSelectionMsg
    19 		printItems oneItem useIndex hilightLevel hilightFrameColor ignoreReselect
    19                 printItems oneItem useIndex hilightLevel hilightFrameColor
    20 		arrowLevel smallArrow keyActionStyle toggleSelect strikeOut
    20                 ignoreReselect arrowLevel smallArrow keyActionStyle
    21 		iSearchString items doubleClickMsg'
    21                 returnKeyActionStyle toggleSelect strikeOut iSearchString items
       
    22                 doubleClickMsg'
    22 	 classVariableNames:'RightArrowShadowForm RightArrowLightForm RightArrowForm
    23 	 classVariableNames:'RightArrowShadowForm RightArrowLightForm RightArrowForm
    23 		SmallRightArrowShadowForm SmallRightArrowLightForm
    24                 SmallRightArrowShadowForm SmallRightArrowLightForm
    24 		DefaultForegroundColor DefaultBackgroundColor
    25                 DefaultForegroundColor DefaultBackgroundColor
    25 		DefaultHilightForegroundColor DefaultHilightBackgroundColor
    26                 DefaultHilightForegroundColor DefaultHilightBackgroundColor
    26 		DefaultHilightFrameColor DefaultHilightLevel DefaultFont
    27                 DefaultHilightFrameColor DefaultHilightLevel DefaultFont
    27 		DefaultRightArrowStyle DefaultRightArrowLevel
    28                 DefaultRightArrowStyle DefaultRightArrowLevel
    28 		DefaultDisabledForegroundColor DefaultShadowColor
    29                 DefaultDisabledForegroundColor DefaultShadowColor
    29 		DefaultLightColor'
    30                 DefaultLightColor'
    30 	 poolDictionaries:''
    31 	 poolDictionaries:''
    31 	 category:'Views-Text'
    32 	 category:'Views-Text'
    32 !
    33 !
    33 
    34 
    34 SelectionInListView comment:'
    35 SelectionInListView comment:'
    35 COPYRIGHT (c) 1989 by Claus Gittinger
    36 COPYRIGHT (c) 1989 by Claus Gittinger
    36 	      All Rights Reserved
    37 	      All Rights Reserved
    37 
    38 
    38 $Header: /cvs/stx/stx/libwidg/Attic/SelListV.st,v 1.31 1995-05-08 15:19:27 claus Exp $
    39 $Header: /cvs/stx/stx/libwidg/Attic/SelListV.st,v 1.32 1995-05-09 01:56:42 claus Exp $
    39 '!
    40 '!
    40 
    41 
    41 !SelectionInListView class methodsFor:'documentation'!
    42 !SelectionInListView class methodsFor:'documentation'!
    42 
    43 
    43 copyright
    44 copyright
    54 "
    55 "
    55 !
    56 !
    56 
    57 
    57 version
    58 version
    58 "
    59 "
    59 $Header: /cvs/stx/stx/libwidg/Attic/SelListV.st,v 1.31 1995-05-08 15:19:27 claus Exp $
    60 $Header: /cvs/stx/stx/libwidg/Attic/SelListV.st,v 1.32 1995-05-09 01:56:42 claus Exp $
    60 "
    61 "
    61 !
    62 !
    62 
    63 
    63 documentation
    64 documentation
    64 "
    65 "
   155 	printItems 
   156 	printItems 
   156 	oneItem
   157 	oneItem
   157 
   158 
   158 	keyActionStyle          <Symbol>        controls how to respond to keyboard selects
   159 	keyActionStyle          <Symbol>        controls how to respond to keyboard selects
   159 
   160 
       
   161 	returnKeyActionStyle    <Symbol>        controls how to respond to return key
       
   162 
   160     written spring/summer 89 by claus
   163     written spring/summer 89 by claus
   161     3D Jan 90 by claus
   164     3D Jan 90 by claus
   162     multiselect Jun 92 by claus
   165     multiselect Jun 92 by claus
   163     keyboard-select jun 94 by claus
   166     keyboard-select jun 94 by claus
   164 "
   167 "
   168 "
   171 "
   169     SelectionInListView can be used both in the ST/X way, using action blocks
   172     SelectionInListView can be used both in the ST/X way, using action blocks
   170     or in the traditional mvc way.
   173     or in the traditional mvc way.
   171     with actions:
   174     with actions:
   172 
   175 
   173       simple:
   176       basic interface:
   174 
   177 
   175 	|top slv|
   178         |top slv|
   176 
   179 
   177 	top := StandardSystemView new
   180         top := StandardSystemView new
   178 		label:'select';
   181                 label:'select';
   179 		minExtent:100@100;
   182                 minExtent:100@100;
   180 		maxExtent:300@400;
   183                 maxExtent:300@400;
   181 		extent:200@200.
   184                 extent:200@200.
   182 
   185 
   183 	slv := SelectionInListView new.
   186         slv := SelectionInListView new.
   184 	slv list:(Filename currentDirectory directoryContents).
   187         slv list:#('one' 'two' 'three').
   185 	slv action:[:index | Transcript showCr:'selected ' , index printString].
   188         slv action:[:index | Transcript showCr:'selected ' , index printString].
   186 
   189 
   187 	top add:slv in:(0.0@0.0 corner:1.0@1.0).
   190         top add:slv in:(0.0@0.0 corner:1.0@1.0).
   188 	top open
   191         top open
       
   192 
       
   193 
       
   194       get element instead of index:
       
   195 
       
   196         |top slv|
       
   197 
       
   198         top := StandardSystemView new
       
   199                 label:'select';
       
   200                 minExtent:100@100;
       
   201                 maxExtent:300@400;
       
   202                 extent:200@200.
       
   203 
       
   204         slv := SelectionInListView new.
       
   205         slv list:#('one' 'two' 'three').
       
   206         slv action:[:element | Transcript showCr:'selected ' , element printString].
       
   207         slv useIndex:false.
       
   208 
       
   209         top add:slv in:(0.0@0.0 corner:1.0@1.0).
       
   210         top open
       
   211 
       
   212 
       
   213       concrete example; show filenames:
       
   214       (notice: normally, you would use a FileSelectionList)
       
   215 
       
   216         |top slv|
       
   217 
       
   218         top := StandardSystemView new
       
   219                 label:'select';
       
   220                 minExtent:100@100;
       
   221                 maxExtent:300@400;
       
   222                 extent:200@200.
       
   223 
       
   224         slv := SelectionInListView new.
       
   225         slv list:(Filename currentDirectory directoryContents).
       
   226         slv action:[:index | 
       
   227             Transcript showCr:'selected ' , index printString.
       
   228             Transcript showCr:' the value is: ', slv selectionValue].
       
   229 
       
   230         top add:slv in:(0.0@0.0 corner:1.0@1.0).
       
   231         top open
       
   232 
   189 
   233 
   190       add a scrollbar:
   234       add a scrollbar:
   191 
   235 
   192 	|top slv|
   236         |top slv|
   193 
   237 
   194 	top := StandardSystemView new
   238         top := StandardSystemView new
   195 		label:'select';
   239                 label:'select';
   196 		minExtent:100@100;
   240                 minExtent:100@100;
   197 		maxExtent:300@400;
   241                 maxExtent:300@400;
   198 		extent:200@200.
   242                 extent:200@200.
   199 
   243 
   200 	slv := SelectionInListView new.
   244         slv := SelectionInListView new.
   201 	slv list:(Filename currentDirectory directoryContents).
   245         slv list:(Filename currentDirectory directoryContents).
   202 	slv action:[:index | Transcript showCr:'selected ' , index printString].
   246         slv action:[:index | Transcript showCr:'selected ' , index printString].
   203 
   247 
   204 	top add:(ScrollableView forView:slv) in:(0.0@0.0 corner:1.0@1.0).
   248         top add:(ScrollableView forView:slv) in:(0.0@0.0 corner:1.0@1.0).
   205 	top open
   249         top open
       
   250 
   206 
   251 
   207       allow reselect (clicking on already selected entry):
   252       allow reselect (clicking on already selected entry):
   208 
   253 
   209 	|top slv|
   254         |top slv|
   210 
   255 
   211 	top := StandardSystemView new
   256         top := StandardSystemView new
   212 		label:'select';
   257                 label:'select';
   213 		minExtent:100@100;
   258                 minExtent:100@100;
   214 		maxExtent:300@400;
   259                 maxExtent:300@400;
   215 		extent:200@200.
   260                 extent:200@200.
   216 
   261 
   217 	slv := SelectionInListView new.
   262         slv := SelectionInListView new.
   218 	slv list:(Filename currentDirectory directoryContents).
   263         slv list:(Filename currentDirectory directoryContents).
   219 	slv action:[:index | Transcript showCr:'selected ' , index printString].
   264         slv action:[:index | Transcript showCr:'selected ' , index printString].
   220 	slv ignoreReselect:false.
   265         slv ignoreReselect:false.
   221 
   266 
   222 	top add:(ScrollableView forView:slv) in:(0.0@0.0 corner:1.0@1.0).
   267         top add:(ScrollableView forView:slv) in:(0.0@0.0 corner:1.0@1.0).
   223 	top open
   268         top open
       
   269 
   224 
   270 
   225       allow multiple selections:
   271       allow multiple selections:
   226 
   272 
   227 	|top slv|
   273         |top slv|
   228 
   274 
   229 	top := StandardSystemView new
   275         top := StandardSystemView new
   230 		label:'select';
   276                 label:'select';
   231 		minExtent:100@100;
   277                 minExtent:100@100;
   232 		maxExtent:300@400;
   278                 maxExtent:300@400;
   233 		extent:200@200.
   279                 extent:200@200.
   234 
   280 
   235 	slv := SelectionInListView new.
   281         slv := SelectionInListView new.
   236 	slv list:(Filename currentDirectory directoryContents).
   282         slv list:(Filename currentDirectory directoryContents).
   237 	slv action:[:index | Transcript showCr:'selected ' , index printString].
   283         slv action:[:indexList | Transcript showCr:'selected ' , indexList printString].
   238 	slv multipleSelectOk:true.
   284         slv multipleSelectOk:true.
   239 
   285 
   240 	top add:(ScrollableView forView:slv) in:(0.0@0.0 corner:1.0@1.0).
   286         top add:(ScrollableView forView:slv) in:(0.0@0.0 corner:1.0@1.0).
   241 	top open
   287         top open
       
   288 
       
   289 
       
   290       same, not using index:
       
   291 
       
   292         |top slv|
       
   293 
       
   294         top := StandardSystemView new
       
   295                 label:'select';
       
   296                 minExtent:100@100;
       
   297                 maxExtent:300@400;
       
   298                 extent:200@200.
       
   299 
       
   300         slv := SelectionInListView new.
       
   301         slv list:(Filename currentDirectory directoryContents).
       
   302         slv action:[:indexList | Transcript showCr:'selected ' , indexList printString].
       
   303         slv multipleSelectOk:true; useIndex:false.
       
   304 
       
   305         top add:(ScrollableView forView:slv) in:(0.0@0.0 corner:1.0@1.0).
       
   306         top open
       
   307 
   242 
   308 
   243       strikeout mode (single):
   309       strikeout mode (single):
   244 
   310 
   245 	|top slv|
   311         |top slv|
   246 
   312 
   247 	top := StandardSystemView new
   313         top := StandardSystemView new
   248 		label:'select';
   314                 label:'select';
   249 		minExtent:100@100;
   315                 minExtent:100@100;
   250 		maxExtent:300@400;
   316                 maxExtent:300@400;
   251 		extent:200@200.
   317                 extent:200@200.
   252 
   318 
   253 	slv := SelectionInListView new.
   319         slv := SelectionInListView new.
   254 	slv list:(Filename currentDirectory directoryContents).
   320         slv list:(Filename currentDirectory directoryContents).
   255 	slv action:[:index | Transcript showCr:'selected ' , index printString].
   321         slv action:[:index | Transcript showCr:'selected ' , index printString].
   256 	slv strikeOut:true.
   322         slv strikeOut:true.
   257 
   323 
   258 	top add:(ScrollableView forView:slv) in:(0.0@0.0 corner:1.0@1.0).
   324         top add:(ScrollableView forView:slv) in:(0.0@0.0 corner:1.0@1.0).
   259 	top open
   325         top open
       
   326 
   260 
   327 
   261       strikeout mode (multiple):
   328       strikeout mode (multiple):
   262 
   329 
   263 	|top slv|
   330         |top slv|
   264 
   331 
   265 	top := StandardSystemView new
   332         top := StandardSystemView new
   266 		label:'select';
   333                 label:'select';
   267 		minExtent:100@100;
   334                 minExtent:100@100;
   268 		maxExtent:300@400;
   335                 maxExtent:300@400;
   269 		extent:200@200.
   336                 extent:200@200.
   270 
   337 
   271 	slv := SelectionInListView new.
   338         slv := SelectionInListView new.
   272 	slv list:(Filename currentDirectory directoryContents).
   339         slv list:(Filename currentDirectory directoryContents).
   273 	slv action:[:index | Transcript showCr:'selected ' , index printString].
   340         slv action:[:index | Transcript showCr:'selected ' , index printString].
   274 	slv strikeOut:true; multipleSelectOk:true.
   341         slv strikeOut:true; multipleSelectOk:true.
   275 
   342 
   276 	top add:(ScrollableView forView:slv) in:(0.0@0.0 corner:1.0@1.0).
   343         top add:(ScrollableView forView:slv) in:(0.0@0.0 corner:1.0@1.0).
   277 	top open
   344         top open
       
   345 
   278 
   346 
   279       define what to do on double-click:
   347       define what to do on double-click:
   280 
   348 
   281 	|top slv|
   349         |top slv|
   282 
   350 
   283 	top := StandardSystemView new
   351         top := StandardSystemView new
   284 		label:'select';
   352                 label:'select';
   285 		minExtent:100@100;
   353                 minExtent:100@100;
   286 		maxExtent:300@400;
   354                 maxExtent:300@400;
   287 		extent:200@200.
   355                 extent:200@200.
   288 
   356 
   289 	slv := SelectionInListView new.
   357         slv := SelectionInListView new.
   290 	slv list:(Filename currentDirectory directoryContents).
   358         slv list:(Filename currentDirectory directoryContents).
   291 	slv action:[:index | Transcript showCr:'selected ' , index printString].
   359         slv action:[:index | Transcript showCr:'selected ' , index printString].
   292 	slv doubleClickAction:[:index | slv selectionValue asFilename edit].
   360         slv doubleClickAction:[:index | Transcript showCr:'doubleclick on ' , index printString].
   293 
   361 
   294 	top add:(ScrollableView forView:slv) in:(0.0@0.0 corner:1.0@1.0).
   362         top add:(ScrollableView forView:slv) in:(0.0@0.0 corner:1.0@1.0).
   295 	top open
   363         top open
   296 
   364 
   297 
   365 
   298     using a Model:
   366     using a Model:
   299 
   367 
   300 	|top slv model|
   368         |top slv model|
   301 
   369 
   302 	model := Plug new.
   370         model := Plug new.
   303 	model respondTo:#getList with:[#('foo' 'bar' 'baz' 'hello')].
   371         model respondTo:#getList with:[#('foo' 'bar' 'baz' 'hello')].
   304 	model respondTo:#initial with:[1].
   372         model respondTo:#initial with:[1].
   305 	model respondTo:#setSelection: with:[:arg | Transcript showCr:'model selected:', arg printString].
   373         model respondTo:#setSelection: with:[:arg | Transcript showCr:'model selected:', arg printString].
   306 
   374 
   307 	top := StandardSystemView new
   375         top := StandardSystemView new
   308 		label:'select';
   376                 label:'select';
   309 		minExtent:100@100;
   377                 minExtent:100@100;
   310 		maxExtent:300@400;
   378                 maxExtent:300@400;
   311 		extent:200@200.
   379                 extent:200@200.
   312 
   380 
   313 	slv := SelectionInListView 
   381         slv := SelectionInListView 
   314 		   on:model
   382                    on:model
   315 		   aspect:#someAspect
   383                    aspect:#someAspect
   316 		   change:#setSelection:
   384                    change:#setSelection:
   317 		   list:#getList
   385                    list:#getList
   318 		   initialSelection:#initial.
   386                    initialSelection:#initial.
   319 
   387 
   320 	top add:(ScrollableView forView:slv) in:(0.0@0.0 corner:1.0@1.0).
   388         top add:(ScrollableView forView:slv) in:(0.0@0.0 corner:1.0@1.0).
   321 	top open
   389         top open
   322 
   390 
   323       notice, that the ST-80 behavaior on reselect is to send a selection change
   391       notice, that the ST-80 behavaior on reselect is to send a selection change
   324       with an index of 0.
   392       with an index of 0.
   325 
   393 
   326 
   394 
       
   395     same, with useIndex false:
       
   396 
       
   397         |top slv model|
       
   398 
       
   399         model := Plug new.
       
   400         model respondTo:#getList with:[#('foo' 'bar' 'baz' 'hello')].
       
   401         model respondTo:#initial with:['bar'].
       
   402         model respondTo:#setSelection: with:[:arg | Transcript showCr:'model selected:', arg printString].
       
   403 
       
   404         top := StandardSystemView new
       
   405                 label:'select';
       
   406                 minExtent:100@100;
       
   407                 maxExtent:300@400;
       
   408                 extent:200@200.
       
   409 
       
   410         slv := SelectionInListView 
       
   411                    on:model
       
   412                    aspect:#someAspect
       
   413                    change:#setSelection:
       
   414                    list:#getList
       
   415                    initialSelection:#initial.
       
   416         slv useIndex:false.
       
   417 
       
   418         top add:(ScrollableView forView:slv) in:(0.0@0.0 corner:1.0@1.0).
       
   419         top open
       
   420 
       
   421 
   327     using a SelectionInList-Model:
   422     using a SelectionInList-Model:
   328     (see how changes in the model (via list:...) are reflected in the view)
   423     (see how changes in the model (via list:...) are reflected in the view)
   329 
   424 
   330 	|top slv model|
   425         |top slv model|
   331 
   426 
   332 	model := SelectionInList with:#('foo' 'bar' 'baz' 'hello').
   427         model := SelectionInList with:#('foo' 'bar' 'baz' 'hello').
   333 
   428         model selection:'bar'.
   334 	top := StandardSystemView new
   429 
   335 		label:'select';
   430         top := StandardSystemView new
   336 		minExtent:100@100;
   431                 label:'select';
   337 		maxExtent:300@400;
   432                 minExtent:100@100;
   338 		extent:200@200.
   433                 maxExtent:300@400;
   339 
   434                 extent:200@200.
   340 	slv := SelectionInListView 
   435 
   341 		   on:model
   436         slv := SelectionInListView on:model.
   342 		   aspect:#list 
   437 
   343 		   change:#selection:
   438         top add:(ScrollableView forView:slv) in:(0.0@0.0 corner:1.0@1.0).
   344 		   list:#list 
   439         top open.
   345 		   initialSelection:#selection.
   440 
   346 
   441         model inspect
   347 	top add:(ScrollableView forView:slv) in:(0.0@0.0 corner:1.0@1.0).
   442 
   348 	top open.
   443 
   349 	model inspect
   444     two selectionInListViews on the same selectionInList model:
   350 
   445 
   351 
   446         |top1 slv1 top2 slv2 model|
   352     since the above selectors are the default anyway, you can also use:
   447 
   353 
   448         model := SelectionInList with:#('foo' 'bar' 'baz' 'hello').
   354 	|top slv model|
   449 
   355 
   450         top1 := StandardSystemView new
   356 	model := SelectionInList with:#('foo' 'bar' 'baz' 'hello').
   451                 label:'select';
   357 
   452                 minExtent:100@100;
   358 	top := StandardSystemView new
   453                 maxExtent:300@400;
   359 		label:'select';
   454                 extent:200@200.
   360 		minExtent:100@100;
   455 
   361 		maxExtent:300@400;
   456         slv1 := SelectionInListView on:model.
   362 		extent:200@200.
   457 
   363 
   458         top1 add:(ScrollableView forView:slv1) in:(0.0@0.0 corner:1.0@1.0).
   364 	slv := SelectionInListView on:model.
   459         top1 open.
   365 
   460 
   366 	top add:(ScrollableView forView:slv) in:(0.0@0.0 corner:1.0@1.0).
   461         top2 := StandardSystemView new
   367 	top open.
   462                 label:'select';
   368 	model inspect
   463                 minExtent:100@100;
       
   464                 maxExtent:300@400;
       
   465                 extent:200@200.
       
   466 
       
   467         slv2 := SelectionInListView on:model.
       
   468 
       
   469         top2 add:(ScrollableView forView:slv2) in:(0.0@0.0 corner:1.0@1.0).
       
   470         top2 open.
   369 "
   471 "
   370 ! !
   472 ! !
   371 
   473 
   372 !SelectionInListView class methodsFor:'instance creation'!
   474 !SelectionInListView class methodsFor:'instance creation'!
   373 
   475 
   383 		 change:change 
   485 		 change:change 
   384 		 list:list 
   486 		 list:list 
   385 		 menu:menu
   487 		 menu:menu
   386 		 initialSelection:initial
   488 		 initialSelection:initial
   387 		 useIndex:useIndex
   489 		 useIndex:useIndex
       
   490 !
       
   491 
       
   492 on:aModel aspect:aspect change:change list:list initialSelection:initial
       
   493     ^ self on:aModel
       
   494 	    printItems:true 
       
   495 	    oneItem:false 
       
   496 	    aspect:aspect
       
   497 	    change:change 
       
   498 	    list:list 
       
   499 	    menu:nil 
       
   500 	    initialSelection:initial 
       
   501 	    useIndex:true 
   388 !
   502 !
   389 
   503 
   390 on:aModel printItems:print oneItem:one aspect:aspect
   504 on:aModel printItems:print oneItem:one aspect:aspect
   391 	      change:change list:list menu:menu initialSelection:initial
   505 	      change:change list:list menu:menu initialSelection:initial
   392 
   506 
   411 	    change:change 
   525 	    change:change 
   412 	    list:list 
   526 	    list:list 
   413 	    menu:menu
   527 	    menu:menu
   414 	    initialSelection:initial 
   528 	    initialSelection:initial 
   415 	    useIndex:true 
   529 	    useIndex:true 
   416 !
       
   417 
       
   418 on:aModel aspect:aspect change:change list:list initialSelection:initial
       
   419     ^ self on:aModel
       
   420 	    printItems:true 
       
   421 	    oneItem:false 
       
   422 	    aspect:aspect
       
   423 	    change:change 
       
   424 	    list:list 
       
   425 	    menu:nil 
       
   426 	    initialSelection:initial 
       
   427 	    useIndex:true 
       
   428 ! !
   530 ! !
   429 
   531 
   430 !SelectionInListView class methodsFor:'defaults'!
   532 !SelectionInListView class methodsFor:'defaults'!
       
   533 
       
   534 defaultListMessage
       
   535     ^ #list 
       
   536 !
       
   537 
       
   538 defaultChangeMessage
       
   539     ^ #selectionIndex: 
       
   540 !
       
   541 
       
   542 defaultAspectMessage
       
   543     ^ nil
       
   544 !
       
   545 
       
   546 defaultSelectionMessage
       
   547     ^ #selectionIndex 
       
   548 !
   431 
   549 
   432 rightArrowShadowFormOn:aDevice
   550 rightArrowShadowFormOn:aDevice
   433     "return the form used for the right arrow light pixels (3D only)"
   551     "return the form used for the right arrow light pixels (3D only)"
   434 
   552 
   435     |f|
   553     |f|
   602 	SmallRightArrowShadowForm := f
   720 	SmallRightArrowShadowForm := f
   603     ].
   721     ].
   604     ^ f
   722     ^ f
   605 ! !
   723 ! !
   606 
   724 
       
   725 !SelectionInListView methodsFor:'selections'!
       
   726 
       
   727 isInSelection:aNumber
       
   728     "return true, if line, aNumber is in the selection"
       
   729 
       
   730     selection isNil ifTrue:[^ false].
       
   731     multipleSelectOk ifTrue:[
       
   732 	^ (selection includes:aNumber)
       
   733     ].
       
   734     ^ (aNumber == selection)
       
   735 !
       
   736 
       
   737 selectWithoutScroll:aNumberOrNilOrCollection
       
   738     "select line, aNumber or deselect if argument is nil"
       
   739 
       
   740     |prevSelection newSelection|
       
   741 
       
   742     newSelection := aNumberOrNilOrCollection.
       
   743     newSelection notNil ifTrue:[
       
   744 	(self isValidSelection:newSelection) ifFalse:[
       
   745 	    newSelection := nil
       
   746 	]
       
   747     ].
       
   748 
       
   749     (newSelection = selection) ifTrue: [^ self].
       
   750 
       
   751     "
       
   752      redraw old selection unhighlighted
       
   753     "
       
   754     selection notNil ifTrue: [
       
   755 	prevSelection := selection.
       
   756 	selection := nil.
       
   757 	multipleSelectOk ifTrue:[
       
   758 	    prevSelection do:[:line |
       
   759 		self redrawElement:line
       
   760 	    ]
       
   761 	] ifFalse:[
       
   762 	    self redrawElement:prevSelection
       
   763 	]
       
   764     ].
       
   765 
       
   766     selection := newSelection.
       
   767 
       
   768     "
       
   769      redraw new selection unhighlighted
       
   770     "
       
   771     newSelection notNil ifTrue:[
       
   772 	multipleSelectOk ifTrue:[
       
   773 	    newSelection isCollection ifFalse:[
       
   774 		selection := OrderedCollection with:newSelection.
       
   775 	    ].
       
   776 	    selection do:[:line |
       
   777 		self redrawElement:line
       
   778 	    ]
       
   779 	] ifFalse:[
       
   780 	    self redrawElement:selection
       
   781 	]
       
   782     ]
       
   783 
       
   784 !
       
   785 
       
   786 makeSelectionVisible
       
   787     "scroll to make the selection line visible"
       
   788 
       
   789     |line|
       
   790 
       
   791     selection notNil ifTrue:[
       
   792 	multipleSelectOk ifTrue:[
       
   793 	    line := selection first.
       
   794 	] ifFalse:[
       
   795 	    line := selection
       
   796 	].
       
   797 	self makeLineVisible:line 
       
   798     ]
       
   799 !
       
   800 
       
   801 selection:aNumberOrNil
       
   802     "select line, aNumber or deselect if argument is nil;
       
   803      scroll to make the selected line visible"
       
   804 
       
   805     self selectWithoutScroll:aNumberOrNil.
       
   806     selection notNil ifTrue:[self makeSelectionVisible]
       
   807 !
       
   808 
       
   809 selectionValue
       
   810     "return the selection value i.e. the text in the selected line.
       
   811      For multiple selections a collection containing the entries is returned."
       
   812 
       
   813     selection isNil ifTrue:[^ nil].
       
   814 
       
   815     multipleSelectOk ifTrue:[
       
   816 	^ selection collect:[:nr | self at:nr]
       
   817     ].
       
   818     ^ self at:selection
       
   819 
       
   820 !
       
   821 
       
   822 hasSelection
       
   823     "return true, if the view has a selection"
       
   824 
       
   825     ^ selection notNil 
       
   826 !
       
   827 
       
   828 selectElement:anObject
       
   829     "select the element with same printString as the argument, anObject.
       
   830      Scroll to make the new selection visible."
       
   831 
       
   832     |lineNo|
       
   833 
       
   834     list notNil ifTrue:[
       
   835 	items notNil ifTrue:[
       
   836 	    lineNo := items indexOf:anObject ifAbsent:nil
       
   837 	] ifFalse:[
       
   838 	    lineNo := list indexOf:(anObject printString) ifAbsent:nil.
       
   839 	].
       
   840 	lineNo notNil ifTrue:[self selection:lineNo]
       
   841     ]
       
   842 !
       
   843 
       
   844 selection
       
   845     "return the selection index or collection of indices (if multipleSelect is on)"
       
   846 
       
   847     ^ selection
       
   848 !
       
   849 
       
   850 selectionChangedFrom:oldSelection
       
   851     "selection has changed. Call actionblock and/or send changeMessage if defined"
       
   852 
       
   853     |arg|
       
   854 
       
   855     arg := self argForChangeMessage.
       
   856     "
       
   857      the ST/X way of doing things - perform actionBlock
       
   858     "
       
   859     actionBlock notNil ifTrue:[actionBlock value:arg].
       
   860     "
       
   861      the ST-80 way of doing things - notify model via changeMsg
       
   862     "
       
   863     "/ ST80 sends 0 as index, if the same selection is reselected ...
       
   864     selection == oldSelection ifTrue:[
       
   865 	arg := 0
       
   866     ].
       
   867     self sendChangeMessageWith:arg
       
   868 !
       
   869 
       
   870 deselect
       
   871     "deselect"
       
   872 
       
   873     self selection:nil
       
   874 !
       
   875 
       
   876 deselectWithoutRedraw
       
   877     "deselect - no redraw"
       
   878 
       
   879     selection := nil
       
   880 !
       
   881 
       
   882 numberOfSelections
       
   883     "return the number of selected entries"
       
   884 
       
   885     |sz|
       
   886 
       
   887     selection isNil ifTrue:[^ 0].
       
   888     sz := selection size.
       
   889     sz > 0 ifTrue:[^ sz].
       
   890     ^ 1
       
   891 !
       
   892 
       
   893 valueIsInSelection:someString
       
   894     "return true, if someString is in the selection"
       
   895 
       
   896     |sel|
       
   897 
       
   898     selection isNil ifTrue:[^ false].
       
   899     sel := self selectionValue.
       
   900     self numberOfSelections > 1 ifTrue:[
       
   901 	^ (sel includes:someString)
       
   902     ].
       
   903     ^ (someString = sel)
       
   904 !
       
   905 
       
   906 selectElementWithoutScroll:anObject
       
   907     "select the element with same printString as the argument, anObject.
       
   908      Do not scroll."
       
   909 
       
   910     |lineNo|
       
   911 
       
   912     list notNil ifTrue:[
       
   913 	items notNil ifTrue:[
       
   914 	    lineNo := items indexOf:anObject ifAbsent:nil
       
   915 	] ifFalse:[
       
   916 	    lineNo := list indexOf:(anObject printString) ifAbsent:nil.
       
   917 	].
       
   918 	lineNo notNil ifTrue:[self selectWithoutScroll:lineNo]
       
   919     ]
       
   920 !
       
   921 
       
   922 nextAfterSelection
       
   923     "return the index of the next selectable entry after the selection.
       
   924      Wrap at end."
       
   925 
       
   926     |next|
       
   927 
       
   928     selection isNil ifTrue:[
       
   929 	next := firstLineShown
       
   930     ] ifFalse:[
       
   931 	selection size ~~ 0 ifTrue:[
       
   932 	    next := selection max + 1
       
   933 	] ifFalse:[
       
   934 	    next := selection + 1
       
   935 	].
       
   936     ].
       
   937     (self isValidSelection:next) ifFalse:[
       
   938 	next > self size ifTrue:[
       
   939 	    next := 1.
       
   940 	] ifFalse:[
       
   941 	    [next <= self size
       
   942 	     and:[(self isValidSelection:next) not]] whileTrue:[
       
   943 		next := next + 1
       
   944 	    ].
       
   945 	].
       
   946     ].
       
   947     (self isValidSelection:next) ifFalse:[
       
   948 	next := nil
       
   949     ].
       
   950     ^ next
       
   951 !
       
   952 
       
   953 previousBeforeSelection
       
   954     "return the index of the previous selectable entry before the selection.
       
   955      Wrap at beginning."
       
   956 
       
   957     |prev|
       
   958 
       
   959     selection isNil ifTrue:[
       
   960 	prev := firstLineShown - 1 
       
   961     ] ifFalse:[
       
   962 	selection size ~~ 0 ifTrue:[
       
   963 	    prev := selection min - 1
       
   964 	] ifFalse:[
       
   965 	    prev := selection - 1
       
   966 	].
       
   967     ].
       
   968     (self isValidSelection:prev) ifFalse:[
       
   969 	prev < 1 ifTrue:[
       
   970 	    prev := self size.
       
   971 	] ifFalse:[
       
   972 	    [prev >= 1
       
   973 	     and:[(self isValidSelection:prev) not]] whileTrue:[
       
   974 		prev := prev - 1
       
   975 	    ].
       
   976 	].
       
   977     ].
       
   978     (self isValidSelection:prev) ifFalse:[
       
   979 	prev := nil
       
   980     ].
       
   981     ^ prev
       
   982 
       
   983 !
       
   984 
       
   985 selectAll
       
   986     "select all entries."
       
   987 
       
   988     |oldSelection|
       
   989 
       
   990     multipleSelectOk ifTrue:[
       
   991 	oldSelection := selection.
       
   992 	selection := OrderedCollection withAll:(1 to:self size).
       
   993 	shown ifTrue:[self redraw].
       
   994 	self selectionChangedFrom:oldSelection.
       
   995     ]
       
   996 !
       
   997 
       
   998 toggleSelection:aNumber
       
   999     "toggle selection-state of entry, aNumber"
       
  1000 
       
  1001     (self isInSelection:aNumber) ifTrue:[
       
  1002 	self removeFromSelection:aNumber
       
  1003     ] ifFalse:[
       
  1004 	self addToSelection:aNumber
       
  1005     ]
       
  1006 !
       
  1007 
       
  1008 selectNext
       
  1009     "select next line or first visible if there is currrently no selection.
       
  1010      Wrap at end."
       
  1011 
       
  1012     self selection:(self nextAfterSelection)
       
  1013 !
       
  1014 
       
  1015 selectPrevious
       
  1016     "select previous line or previous visible if there is currently no selection.
       
  1017      Wrap at beginning."
       
  1018 
       
  1019     self selection:(self previouseBeforeSelection).
       
  1020 !
       
  1021 
       
  1022 selectionDo:aBlock
       
  1023     "perform aBlock for each nr in the selection.
       
  1024      For single selection, it is called once for the items nr.
       
  1025      For multiple selections, it is called for each."
       
  1026 
       
  1027     selection notNil ifTrue:[
       
  1028 	multipleSelectOk ifTrue:[
       
  1029 	    selection do:aBlock
       
  1030 	] ifFalse:[
       
  1031 	    aBlock value:selection
       
  1032 	].
       
  1033     ].
       
  1034 
       
  1035 !
       
  1036 
       
  1037 selectionAsCollection
       
  1038     "return the selection as a collection of line numbers.
       
  1039      This allows users of this class to enumerate independent of
       
  1040      the multipleSelect style."
       
  1041 
       
  1042     selection isNil ifTrue:[^ #()].
       
  1043 
       
  1044     multipleSelectOk ifTrue:[
       
  1045 	 ^ (OrderedCollection new) add:selection; yourself.
       
  1046     ].
       
  1047     ^ selection
       
  1048 ! !
       
  1049 
   607 !SelectionInListView methodsFor:'redrawing'!
  1050 !SelectionInListView methodsFor:'redrawing'!
   608 
       
   609 redrawElement:aNumber
       
   610     "redraw an individual element"
       
   611 
       
   612     ^ self redrawLine:aNumber
       
   613 !
       
   614 
  1051 
   615 redrawVisibleLine:visLineNr
  1052 redrawVisibleLine:visLineNr
   616     "redraw a single line.
  1053     "redraw a single line.
   617      Must check, if any is in the selection and handle this case.
  1054      Must check, if any is in the selection and handle this case.
   618      Otherwise draw using supers method."
  1055      Otherwise draw using supers method."
   624     listLine := self visibleLineToListLine:visLineNr.
  1061     listLine := self visibleLineToListLine:visLineNr.
   625     listLine notNil ifTrue:[
  1062     listLine notNil ifTrue:[
   626 	(self isInSelection:listLine) ifTrue:[
  1063 	(self isInSelection:listLine) ifTrue:[
   627 	    ^ self drawVisibleLineSelected:visLineNr
  1064 	    ^ self drawVisibleLineSelected:visLineNr
   628 	].
  1065 	].
   629 	(self line:listLine hasAttribute:#halfIntensity) ifTrue:[
  1066 
   630 	    fg := halfIntensityFgColor
  1067 	listAttributes notNil ifTrue:[
   631 	] ifFalse:[
  1068 	    (self line:listLine hasAttribute:#halfIntensity) ifTrue:[
   632 	    (self line:listLine hasAttribute:#disabled) ifTrue:[
       
   633 		fg := halfIntensityFgColor
  1069 		fg := halfIntensityFgColor
       
  1070 	    ] ifFalse:[
       
  1071 		(self line:listLine hasAttribute:#disabled) ifTrue:[
       
  1072 		    fg := halfIntensityFgColor
       
  1073 		].
   634 	    ].
  1074 	    ].
   635 	].
  1075 	    (self line:listLine hasAttribute:#bold) ifTrue:[
   636 	(self line:listLine hasAttribute:#bold) ifTrue:[
  1076 		font bold ifTrue:[
   637 	    font bold ifTrue:[
  1077 		    "
   638 		"
  1078 		     mhmh - what can be done, if the font is already bold ?
   639 		 mhmh - what can be done, if the font is already bold ?
  1079 		    "
   640 		"
  1080 		    newFont := font.
   641 		newFont := font.
  1081 		    fgColor brightness > 0.5 ifTrue:[
   642 		fgColor brightness > 0.5 ifTrue:[
  1082 			fg := fgColor darkened "darkened". 
   643 		    fg := fgColor darkened "darkened". 
  1083 		    ] ifFalse:[
       
  1084 			fg := fgColor lightened "lightened"
       
  1085 		    ].
       
  1086 		    (fg brightness - bg brightness) abs < 0.25 ifTrue:[
       
  1087 			bgColor brightness > 0.5 ifTrue:[
       
  1088 			    fg := fg darkened. 
       
  1089 			] ifFalse:[
       
  1090 			    fg := fg lightened
       
  1091 			].
       
  1092 		    ]
   644 		] ifFalse:[
  1093 		] ifFalse:[
   645 		    fg := fgColor lightened "lightened"
  1094 		    newFont := font asBold
   646 		].
  1095 		].
   647 		(fg brightness - bg brightness) abs < 0.25 ifTrue:[
  1096 		device setFont:(newFont on:device) fontId in:gcId.
   648 		    bgColor brightness > 0.5 ifTrue:[
  1097 		self drawVisibleLine:visLineNr with:fg and:bg.
   649 			fg := fg darkened. 
  1098 		device setFont:(font on:device) fontId in:gcId.
   650 		    ] ifFalse:[
  1099 		^ self
   651 			fg := fg lightened
  1100 	    ]
   652 		    ].
       
   653 		]
       
   654 	    ] ifFalse:[
       
   655 		newFont := font asBold
       
   656 	    ].
       
   657 	    device setFont:(newFont on:device) fontId in:gcId.
       
   658 	    self drawVisibleLine:visLineNr with:fg and:bg.
       
   659 	    device setFont:(font on:device) fontId in:gcId.
       
   660 	    ^ self
       
   661 	]
  1101 	]
   662     ].
  1102     ].
   663     ^ self drawVisibleLine:visLineNr with:fg and:bg
  1103     ^ self drawVisibleLine:visLineNr with:fg and:bg
       
  1104 !
       
  1105 
       
  1106 redrawElement:aNumber
       
  1107     "redraw an individual element"
       
  1108 
       
  1109     ^ self redrawLine:aNumber
   664 !
  1110 !
   665 
  1111 
   666 drawVisibleLineSelected:visLineNr
  1112 drawVisibleLineSelected:visLineNr
   667     "redraw a single line as selected."
  1113     "redraw a single line as selected."
   668 
  1114 
   777     selNo < endVisLineNr ifTrue:[
  1223     selNo < endVisLineNr ifTrue:[
   778 	super redrawFromVisibleLine:(selNo + 1) to:endVisLineNr
  1224 	super redrawFromVisibleLine:(selNo + 1) to:endVisLineNr
   779     ]
  1225     ]
   780 !
  1226 !
   781 
  1227 
       
  1228 redrawVisibleLine:visLineNr from:startCol to:endCol
       
  1229     "redraw from a startCol to endCol.
       
  1230      Must check, if its in the selection and handle this case."
       
  1231 
       
  1232     (self visibleLineNeedsSpecialCare:visLineNr) ifTrue:[
       
  1233 	^ self redrawVisibleLine:visLineNr
       
  1234     ].
       
  1235     super redrawVisibleLine:visLineNr from:startCol to:endCol
       
  1236 !
       
  1237 
   782 drawRightArrowInVisibleLine:visLineNr
  1238 drawRightArrowInVisibleLine:visLineNr
   783     "draw a right arrow (for submenus).
  1239     "draw a right arrow (for submenus).
   784      This method is not used here, but provided for subclasses such
  1240      This method is not used here, but provided for subclasses such
   785      as menus or file-lists."
  1241      as menus or file-lists."
   786 
  1242 
   838 	^ self redrawVisibleLine:visLineNr
  1294 	^ self redrawVisibleLine:visLineNr
   839     ].
  1295     ].
   840     super redrawVisibleLine:visLineNr col:colNr
  1296     super redrawVisibleLine:visLineNr col:colNr
   841 !
  1297 !
   842 
  1298 
   843 redrawVisibleLine:visLineNr from:startCol to:endCol
       
   844     "redraw from a startCol to endCol.
       
   845      Must check, if its in the selection and handle this case."
       
   846 
       
   847     (self visibleLineNeedsSpecialCare:visLineNr) ifTrue:[
       
   848 	^ self redrawVisibleLine:visLineNr
       
   849     ].
       
   850     super redrawVisibleLine:visLineNr from:startCol to:endCol
       
   851 !
       
   852 
       
   853 redrawVisibleLine:visLineNr from:startCol
  1299 redrawVisibleLine:visLineNr from:startCol
   854     "redraw from a col to the right end.
  1300     "redraw from a col to the right end.
   855      Must check, if its in the selection and handle this case."
  1301      Must check, if its in the selection and handle this case."
   856 
  1302 
   857     (self visibleLineNeedsSpecialCare:visLineNr) ifTrue:[
  1303     (self visibleLineNeedsSpecialCare:visLineNr) ifTrue:[
   858 	^ self redrawVisibleLine:visLineNr
  1304 	^ self redrawVisibleLine:visLineNr
   859     ].
  1305     ].
   860     super redrawVisibleLine:visLineNr from:startCol
  1306     super redrawVisibleLine:visLineNr from:startCol
   861 ! !
  1307 ! !
   862 
  1308 
   863 !SelectionInListView methodsFor:'selections'!
  1309 !SelectionInListView methodsFor:'private'!
   864 
  1310 
   865 selectWithoutScroll:aNumberOrNil
  1311 getListFromModel
   866     "select line, aNumber or deselect if argument is nil"
  1312     "if I have a model and a listMsg, get my list from it"
   867 
  1313 
   868     |prevSelection newSelection|
  1314     |text|
   869 
  1315 
   870     newSelection := aNumberOrNil.
  1316     model notNil ifTrue:[
   871     newSelection notNil ifTrue:[
  1317 	listMsg notNil ifTrue:[
   872 	(self isValidSelection:newSelection) ifFalse:[
  1318 	    items := model perform:listMsg.
   873 	    newSelection := nil
  1319 	    items notNil ifTrue:[
       
  1320 		printItems ifTrue:[
       
  1321 		    text := items collect:[:element | element printString]
       
  1322 		] ifFalse:[
       
  1323 		    text := items
       
  1324 		].
       
  1325 		text notNil ifTrue:[
       
  1326 		    text := text asStringCollection.
       
  1327 		]
       
  1328 	    ].
       
  1329 	    self list:text
       
  1330 	].
       
  1331     ].
       
  1332 !
       
  1333 
       
  1334 getSelectionFromModel
       
  1335     "if I have a model and an initialSelectionMsg, get my selection from it"
       
  1336 
       
  1337     |sel|
       
  1338 
       
  1339     model notNil ifTrue:[
       
  1340 	initialSelectionMsg notNil ifTrue:[
       
  1341 	    sel := model perform:initialSelectionMsg.
       
  1342 	    useIndex ifTrue:[
       
  1343 		self selection:sel 
       
  1344 	    ] ifFalse:[
       
  1345 		self selectElement:sel.
       
  1346 	    ].
   874 	]
  1347 	]
   875     ].
  1348     ].
   876 
  1349 !
   877     (newSelection == selection) ifTrue: [^ self].
  1350 
   878 
  1351 argForChangeMessage
   879     selection notNil ifTrue: [
  1352     "return the argument for a selectionChange;
   880 	prevSelection := selection.
  1353      depending on the setting of useIndex, this is either the numeric
   881 	selection := nil.
  1354      index of the selection or the value (i.e. the string)"
   882 	(prevSelection isCollection) ifTrue:[
  1355 
   883 	    prevSelection do:[:line |
  1356     useIndex ~~ false ifTrue:[  "/ i.e. everything except false
   884 		self redrawElement:line
  1357 	^ selection
       
  1358     ].
       
  1359         
       
  1360     printItems ifFalse:[
       
  1361 	^ self selectionValue
       
  1362     ].
       
  1363 
       
  1364     items notNil ifTrue:[
       
  1365 	multipleSelectOk ifTrue:[
       
  1366 	    ^ selection collect:[:nr | items at:nr]
       
  1367 	].
       
  1368 	^ items at:selection
       
  1369     ].
       
  1370 
       
  1371     ^ nil       "/ cannot happen
       
  1372 !
       
  1373 
       
  1374 isValidSelection:aNumberOrCollection
       
  1375     "return true, if aNumber is ok as a selection index"
       
  1376 
       
  1377     aNumberOrCollection isNil ifTrue:[^ false].
       
  1378 
       
  1379     (aNumberOrCollection isCollection) ifTrue:[
       
  1380 	multipleSelectOk ifFalse:[^ false].
       
  1381 	aNumberOrCollection do:[:index |
       
  1382 	    (index between:1 and:self size) ifFalse:[^ false].
       
  1383 	].
       
  1384 	^ true.
       
  1385     ] ifFalse:[
       
  1386 	^ (aNumberOrCollection between:1 and:self size).
       
  1387     ].
       
  1388 
       
  1389 !
       
  1390 
       
  1391 positionToSelectionX:x y:y
       
  1392     "given a click position, return the selection lineNo"
       
  1393 
       
  1394     |visibleLine|
       
  1395 
       
  1396     (x between:0 and:width) ifTrue:[
       
  1397 	(y between:0 and:height) ifTrue:[
       
  1398 	    visibleLine := self visibleLineOfY:y.
       
  1399 	    ^ self visibleLineToListLine:visibleLine
       
  1400 	]
       
  1401     ].
       
  1402     ^ nil
       
  1403 !
       
  1404 
       
  1405 widthForScrollBetween:start and:end
       
  1406     "has to be redefined since WHOLE line is inverted/modified sometimes"
       
  1407 
       
  1408     | anySelectionInRange |
       
  1409 
       
  1410     selection notNil ifTrue:[
       
  1411 	multipleSelectOk ifTrue:[
       
  1412 	    anySelectionInRange := false.
       
  1413 	    selection do:[:s |
       
  1414 		(s between:start and:end) ifTrue:[
       
  1415 		    anySelectionInRange := true
       
  1416 		]
   885 	    ]
  1417 	    ]
   886 	] ifFalse:[
  1418 	] ifFalse:[
   887 	    self redrawElement:prevSelection
  1419 	    anySelectionInRange := selection between:start and:end
   888 	]
       
   889     ].
       
   890     selection := newSelection.
       
   891     (selection isCollection) ifTrue:[
       
   892 	selection do:[:line |
       
   893 	    self redrawElement:line
       
   894 	]
  1420 	]
   895     ] ifFalse:[
  1421     ] ifFalse:[
   896 	self redrawElement:selection
  1422 	anySelectionInRange := false
       
  1423     ].
       
  1424 
       
  1425     anySelectionInRange ifTrue:[
       
  1426 	^ width
       
  1427 "
       
  1428 	self is3D ifFalse:[
       
  1429 	    ^ width 
       
  1430 	].
       
  1431 	( #(next openwin) includes:style) ifTrue:[
       
  1432 	    ^ width 
       
  1433 	].
       
  1434 	viewBackground = background ifFalse:[
       
  1435 	    ^ width 
       
  1436 	]
       
  1437 "
       
  1438     ].
       
  1439     ^ super widthForScrollBetween:start and:end
       
  1440 !
       
  1441 
       
  1442 visibleLineNeedsSpecialCare:visLineNr
       
  1443     |listLine|
       
  1444 
       
  1445     listLine := self visibleLineToListLine:visLineNr.
       
  1446     listLine isNil ifTrue:[^ false].
       
  1447     (self isInSelection:listLine) ifTrue:[^ true].
       
  1448     listAttributes notNil ifTrue:[
       
  1449 	(listLine <= listAttributes size) ifTrue:[
       
  1450 	    ^ (listAttributes at:listLine) notNil
       
  1451 	]
       
  1452     ].
       
  1453     ^ false
       
  1454 !
       
  1455 
       
  1456 checkRemovingSelection:lineNr
       
  1457     "when a line is removed, we have to adjust selection"
       
  1458 
       
  1459     |newSelection|
       
  1460 
       
  1461     selection notNil ifTrue:[
       
  1462 	multipleSelectOk ifTrue:[
       
  1463 	    newSelection := OrderedCollection new.
       
  1464 	    selection do:[:sel |
       
  1465 		sel < lineNr ifTrue:[
       
  1466 		    newSelection add:sel
       
  1467 		] ifFalse:[
       
  1468 		    sel > lineNr ifTrue:[
       
  1469 			newSelection add:(sel - 1)
       
  1470 		    ]
       
  1471 		    "otherwise remove it from the selection"
       
  1472 		]
       
  1473 	    ].
       
  1474 	    newSelection size == 0 ifTrue:[
       
  1475 		selection := nil
       
  1476 	    ] ifFalse:[
       
  1477 		selection := newSelection
       
  1478 	    ]
       
  1479 	] ifFalse:[
       
  1480 	    selection == lineNr ifTrue:[
       
  1481 		selection := nil
       
  1482 	    ] ifFalse:[
       
  1483 		selection > lineNr ifTrue:[
       
  1484 		    selection := selection - 1
       
  1485 		]
       
  1486 	    ]
       
  1487 	]
   897     ]
  1488     ]
   898 
  1489 !
   899 !
  1490 
   900 
  1491 scrollSelectDown
   901 selection:aNumberOrNil
  1492     "auto scroll action; scroll and reinstall timed-block"
   902     "select line, aNumber or deselect if argument is nil;
  1493 
   903      scroll to make the selected line visible"
  1494     self scrollDown.
   904 
  1495     Processor addTimedBlock:autoScrollBlock afterSeconds:autoScrollDeltaT.
   905     self selectWithoutScroll:aNumberOrNil.
  1496 !
   906     selection notNil ifTrue:[self makeSelectionVisible]
  1497 
   907 !
  1498 scrollSelectUp
   908 
  1499     "auto scroll action; scroll and reinstall timed-block"
   909 makeSelectionVisible
  1500 
   910     "scroll to make the selection line visible"
  1501     self scrollUp.
   911 
  1502     Processor addTimedBlock:autoScrollBlock afterSeconds:autoScrollDeltaT.
   912     |line|
  1503 ! !
   913 
  1504 
   914     selection notNil ifTrue:[
  1505 !SelectionInListView methodsFor:'event handling'!
   915 	(selection isCollection) ifTrue:[
  1506 
   916 	    line := selection first.
  1507 buttonRelease:button x:x y:y
       
  1508     "stop any autoscroll"
       
  1509 
       
  1510     self stopAutoScroll
       
  1511 !
       
  1512 
       
  1513 buttonPress:button x:x y:y
       
  1514     |oldSelection listLineNr|
       
  1515 
       
  1516     ((button == 1) or:[button == #select]) ifTrue:[
       
  1517 	enabled ifTrue:[
       
  1518 	    listLineNr := self visibleLineToListLine:(self visibleLineOfY:y).
       
  1519 	    listLineNr notNil ifTrue:[
       
  1520 		(toggleSelect 
       
  1521 		and:[self isInSelection:listLineNr]) ifTrue:[
       
  1522 		    oldSelection := selection copy.
       
  1523 		    self removeFromSelection:listLineNr
       
  1524 		] ifFalse:[
       
  1525 		    (self line:listLineNr hasAttribute:#disabled) ifTrue:[^ self].
       
  1526 
       
  1527 		    (selectConditionBlock notNil 
       
  1528 		     and:[(selectConditionBlock value:listLineNr) not]) ifTrue:[^ self].
       
  1529 
       
  1530 		    (toggleSelect and:[multipleSelectOk]) ifTrue:[
       
  1531 			oldSelection := selection copy.
       
  1532 			self addToSelection:listLineNr
       
  1533 		    ] ifFalse:[
       
  1534 			oldSelection := selection copy.
       
  1535 			self selectWithoutScroll:listLineNr.
       
  1536 		    ].
       
  1537 		].
       
  1538 		((ignoreReselect not and:[selection notNil])
       
  1539 		 or:[selection ~= oldSelection]) ifTrue:[
       
  1540 		    self selectionChangedFrom:oldSelection.
       
  1541 		].
       
  1542 		clickLine := listLineNr
       
  1543 	    ].
       
  1544 	]
       
  1545     ] ifFalse:[
       
  1546 	super buttonPress:button x:x y:y
       
  1547     ]
       
  1548 !
       
  1549 
       
  1550 sizeChanged:how
       
  1551     "if there is a selection, make certain, its visible
       
  1552      after the sizechange"
       
  1553 
       
  1554     |first wasAtEnd|
       
  1555 
       
  1556     wasAtEnd := (firstLineShown + nFullLinesShown) >= self size.
       
  1557 
       
  1558     super sizeChanged:how.
       
  1559 
       
  1560     shown ifTrue:[
       
  1561 	selection notNil ifTrue:[
       
  1562 	    multipleSelectOk ifTrue:[
       
  1563 		first := selection first
       
  1564 	    ] ifFalse:[
       
  1565 		first := selection
       
  1566 	    ].
       
  1567 	    first notNil ifTrue:[self makeLineVisible:first]
   917 	] ifFalse:[
  1568 	] ifFalse:[
   918 	    line := selection
  1569 	    "
   919 	].
  1570 	     if we where at the end before, move to the end again.
   920 	self makeLineVisible:line 
  1571 	     Still to be seen, if this is better in real life ...
       
  1572 	    "
       
  1573 	    wasAtEnd ifTrue:[
       
  1574 		"at end"
       
  1575 		self scrollToBottom
       
  1576 	    ]
       
  1577 	]
   921     ]
  1578     ]
   922 !
  1579 !
   923 
  1580 
   924 isInSelection:aNumber
  1581 keyPress:key x:x y:y
   925     "return true, if line, aNumber is in the selection"
  1582     "handle keyboard input"
   926 
  1583 
   927     selection isNil ifTrue:[^ false].
  1584     |index startSearch backSearch searchPrefix|
   928     selection isCollection ifTrue:[
  1585 
   929 	^ (selection includes:aNumber)
  1586     (key == #CursorUp) ifTrue:[
   930     ].
  1587         index := self previousBeforeSelection.
   931     ^ (aNumber == selection)
  1588         self key:key select:index x:x y:y.
   932 !
  1589         ^ self
   933 
  1590     ].
   934 toggleSelect:aBoolean
  1591     (key == #CursorDown) ifTrue:[
   935     "turn on/off toggle select"
  1592         index := self nextAfterSelection.
   936 
  1593         self key:key select:index x:x y:y.
   937     toggleSelect := aBoolean.
  1594         ^ self
   938 !
  1595     ].
   939 
  1596     "/
   940 multipleSelectOk:aBoolean
  1597     "/ stupid: Home and End are cought in ScrollableView
   941     "allow/disallow multiple selections"
  1598     "/ we normally do not get them ...
   942 
  1599     "/ (need to call handlesKey: from there ...
   943     multipleSelectOk := aBoolean.
  1600     "/  ... and implement it here)
   944     aBoolean ifTrue:[
  1601     "/
   945 	self enableButtonMotionEvents
  1602     (key == #Home) ifTrue:[
       
  1603         self key:key select:1 x:x y:y.
       
  1604         ^ self
       
  1605     ].
       
  1606     (key == #End) ifTrue:[
       
  1607         index := self size.
       
  1608         self key:key select:index x:x y:y.
       
  1609         ^ self
       
  1610     ].
       
  1611     key == #Return ifTrue:[
       
  1612         returnKeyActionStyle == #doubleClick ifTrue:[
       
  1613             selection notNil ifTrue:[
       
  1614                 self doubleClicked
       
  1615             ].
       
  1616             ^ self
       
  1617         ].
       
  1618         returnKeyActionStyle ~~ #pass ifTrue:[
       
  1619             ^ self
       
  1620         ].
       
  1621     ].
       
  1622 
       
  1623     "
       
  1624      alphabetic keys: search for next entry
       
  1625      starting with keys character. If shift is pressed, search backward
       
  1626     "
       
  1627     (self size > 0
       
  1628     and:[key isCharacter
       
  1629     and:[key isLetter]]) ifTrue:[
       
  1630         keyActionStyle isNil ifTrue:[^ self].
       
  1631         keyActionStyle == #pass ifFalse:[
       
  1632             searchPrefix := key asLowercase asString.
       
  1633 
       
  1634 "/            ... isISearch... ifFalse:[
       
  1635 "/                iSearchString := ''
       
  1636 "/            ] ifTrue:[
       
  1637 "/                iSearchString := iSearchString , searchPrefix.
       
  1638 "/                searchPrefix := iSearchString
       
  1639 "/            ].
       
  1640 
       
  1641             backSearch := device shiftDown.
       
  1642             backSearch ifTrue:[
       
  1643                 selection notNil ifTrue:[
       
  1644                     selection size > 0 ifTrue:[
       
  1645                         startSearch := selection first - 1
       
  1646                     ] ifFalse:[
       
  1647                         startSearch := selection - 1
       
  1648                     ]
       
  1649                 ] ifFalse:[
       
  1650                     startSearch := self size
       
  1651                 ].
       
  1652                 startSearch < 1 ifTrue:[
       
  1653                     startSearch := self size.
       
  1654                 ].
       
  1655             ] ifFalse:[    
       
  1656                 selection notNil ifTrue:[
       
  1657                     selection size > 0 ifTrue:[
       
  1658                         startSearch := selection last + 1
       
  1659                     ] ifFalse:[
       
  1660                         startSearch := selection + 1
       
  1661                     ]
       
  1662                 ] ifFalse:[
       
  1663                     startSearch := 1
       
  1664                 ].
       
  1665                 startSearch > self size ifTrue:[
       
  1666                     startSearch := 1.
       
  1667                 ].
       
  1668             ].
       
  1669             index := startSearch.
       
  1670             [true] whileTrue:[
       
  1671                 (((self at:index) asString) asLowercase startsWith:searchPrefix) ifTrue:[
       
  1672                     index = selection ifTrue:[^ self].
       
  1673                     ^ self key:key select:index x:x y:y
       
  1674                 ].
       
  1675                 backSearch ifTrue:[
       
  1676                     index := index - 1.
       
  1677                     index < 1 ifTrue:[index := self size]
       
  1678                 ] ifFalse:[
       
  1679                     index := index + 1.
       
  1680                     index > self size ifTrue:[index := 1].
       
  1681                 ].
       
  1682                 index == startSearch ifTrue:[
       
  1683                     ^ self
       
  1684                 ]
       
  1685             ]
       
  1686         ].
       
  1687     ].
       
  1688     ^ super keyPress:key x:x y:y
       
  1689 !
       
  1690 
       
  1691 buttonMotion:buttonMask x:x y:y
       
  1692     "mouse-move while button was pressed - handle selection changes"
       
  1693 
       
  1694     |movedVisibleLine movedLine delta oldSelection oldSelCount|
       
  1695 
       
  1696     "is it the select or 1-button ?"
       
  1697     (device buttonMotionMask:buttonMask includesButton:#select) ifFalse:[
       
  1698 	(device buttonMotionMask:buttonMask includesButton:1) ifFalse:[
       
  1699 	    ^ self
       
  1700 	].
       
  1701     ].
       
  1702 
       
  1703     clickLine isNil ifTrue:[^ self].
       
  1704 
       
  1705     "if moved outside of view, start autoscroll"
       
  1706     (y < 0) ifTrue:[
       
  1707 	self compressMotionEvents:false.
       
  1708 	self startAutoScrollUp:y.
       
  1709 	^ self
       
  1710     ].
       
  1711     (y > height) ifTrue:[
       
  1712 	self compressMotionEvents:false.
       
  1713 	self startAutoScrollDown:(y - height).
       
  1714 	^ self
       
  1715     ].
       
  1716 
       
  1717     "move inside - stop autoscroll if any"
       
  1718     self stopAutoScroll.
       
  1719 
       
  1720     movedVisibleLine := self visibleLineOfY:y.
       
  1721     movedLine := self visibleLineToAbsoluteLine:movedVisibleLine.
       
  1722     (movedLine == clickLine) ifTrue:[^ self].
       
  1723 
       
  1724     multipleSelectOk ifTrue:[
       
  1725 	delta := (clickLine < movedLine) ifTrue:[1] ifFalse:[-1].
       
  1726 
       
  1727 	oldSelection := selection.
       
  1728 	oldSelCount := selection size.
       
  1729 
       
  1730 	(clickLine+delta) to:movedLine by:delta do:[:line |
       
  1731 	    (self isInSelection:line) ifTrue:[
       
  1732 		self removeFromSelection:line
       
  1733 	    ] ifFalse:[
       
  1734 		self addToSelection:line
       
  1735 	    ]
       
  1736 	].
       
  1737 	((selection ~= oldSelection)
       
  1738 	 or:[selection size ~~ oldSelCount]) ifTrue:[
       
  1739 	    self selectionChangedFrom:oldSelection.
       
  1740 	]
   946     ] ifFalse:[
  1741     ] ifFalse:[
   947 	self disableButtonMotionEvents
  1742 "/        self selectWithoutScroll:movedLine
   948     ] 
  1743     ].
       
  1744 
       
  1745     clickLine := movedLine
       
  1746 !
       
  1747 
       
  1748 key:key select:index x:x y:y
       
  1749     "select an entry by a keyboard action.
       
  1750      This is treated like a doubleClick on that entry"
       
  1751 
       
  1752     |oldSelection|
       
  1753 
       
  1754     (selectConditionBlock isNil or:[selectConditionBlock value:index]) ifTrue:[
       
  1755         keyActionStyle notNil ifTrue:[
       
  1756             keyActionStyle == #pass ifTrue:[
       
  1757                 ^ super keyPress:key x:x y:y
       
  1758             ].
       
  1759             oldSelection := selection.
       
  1760             self selection:index.
       
  1761             self selectionChangedFrom:oldSelection.
       
  1762             keyActionStyle == #selectAndDoubleClick ifTrue:[
       
  1763                 self doubleClicked
       
  1764             ]
       
  1765         ]
       
  1766     ].
       
  1767 !
       
  1768 
       
  1769 buttonMultiPress:button x:x y:y
       
  1770     ((button == 1) or:[button == #select]) ifTrue:[
       
  1771 "/        doubleClickActionBlock isNil ifTrue:[
       
  1772 "/            self buttonPress:button x:x y:y
       
  1773 "/        ].
       
  1774 	self doubleClicked.
       
  1775     ] ifFalse:[
       
  1776 	super buttonMultiPress:button x:x y:y
       
  1777     ]
       
  1778 !
       
  1779 
       
  1780 buttonShiftPress:button x:x y:y
       
  1781     "add to the selection (if multipleSelectOk); otherwise,
       
  1782      behave like normal select"
       
  1783 
       
  1784     |oldSelection listLineNr|
       
  1785 
       
  1786     ((button == 1) or:[button == #select]) ifTrue:[
       
  1787 	toggleSelect ifTrue:[
       
  1788 	    ^ self buttonPress:button x:x y:y
       
  1789 	].
       
  1790 	enabled ifTrue:[
       
  1791 	    listLineNr := self visibleLineToListLine:(self visibleLineOfY:y).
       
  1792 	    listLineNr notNil ifTrue:[
       
  1793 		(self line:listLineNr hasAttribute:#disabled) ifTrue:[^ self].
       
  1794 
       
  1795 		(selectConditionBlock notNil 
       
  1796 		 and:[(selectConditionBlock value:listLineNr) not]) ifTrue:[^ self].
       
  1797 	    ].
       
  1798 	    oldSelection := selection copy.
       
  1799 	    listLineNr notNil ifTrue: [
       
  1800 		multipleSelectOk ifTrue:[
       
  1801 		    (self isInSelection:listLineNr) ifTrue:[
       
  1802 			self removeFromSelection:listLineNr
       
  1803 		    ] ifFalse:[
       
  1804 			self addToSelection:listLineNr
       
  1805 		    ]
       
  1806 		] ifFalse:[
       
  1807 		    self selectWithoutScroll:listLineNr
       
  1808 		]
       
  1809 	    ].
       
  1810 	    ((ignoreReselect not and:[selection notNil])
       
  1811 	     or:[selection ~= oldSelection]) ifTrue:[
       
  1812 		self selectionChangedFrom:oldSelection.
       
  1813 	    ].
       
  1814 	    clickLine := listLineNr
       
  1815 	]
       
  1816     ] ifFalse:[
       
  1817 	super buttonShiftPress:button x:x y:y
       
  1818     ]
       
  1819 !
       
  1820 
       
  1821 doubleClicked
       
  1822     doubleClickActionBlock notNil ifTrue:[doubleClickActionBlock value:selection].
       
  1823     (model notNil and:[doubleClickMsg notNil]) ifTrue:[
       
  1824 	self sendChangeMessage:doubleClickMsg with:(self argForChangeMessage).
       
  1825     ].
       
  1826 ! !
       
  1827 
       
  1828 !SelectionInListView methodsFor:'accessing-actions'!
       
  1829 
       
  1830 action:aBlock
       
  1831     "set the action block to be performed on select"
       
  1832 
       
  1833     actionBlock := aBlock
       
  1834 !
       
  1835 
       
  1836 doubleClickAction:aBlock
       
  1837     "set the double click action block to be performed on select"
       
  1838 
       
  1839     doubleClickActionBlock := aBlock
   949 !
  1840 !
   950 
  1841 
   951 selectConditionBlock:aBlock
  1842 selectConditionBlock:aBlock
   952     "set the conditionBlock; this block is evaluated before a selection
  1843     "set the conditionBlock; this block is evaluated before a selection
   953      change is performed; the change will not be done, if the evaluation
  1844      change is performed; the change will not be done, if the evaluation
   955      the SystemBrowser"
  1846      the SystemBrowser"
   956 
  1847 
   957     selectConditionBlock := aBlock
  1848     selectConditionBlock := aBlock
   958 !
  1849 !
   959 
  1850 
   960 strikeOut:aBoolean
  1851 useIndex:aBoolean
   961     "turn on/off strikeOut mode"
  1852     "set/clear the useIndex flag. If set, both actionBlock and change-messages
   962 
  1853      are passed the index(indices) of the selection as argument. 
   963     strikeOut := aBoolean.
  1854      If clear, the value(s) (i.e. the selected string) is passed.
   964 !
  1855      Default is true."
   965 
  1856 
   966 selection
  1857     useIndex := aBoolean
   967     "return the selection line nr or collection of line numbers"
  1858 !
   968 
  1859 
   969     ^ selection
  1860 keyActionStyle:aSymbol
   970 !
  1861     "defines how the view should respond to alpha-keys pressed.
   971 
  1862      Possible values are:
   972 ignoreReselect:aBoolean
  1863 	#select               -> will select next entry starting with that
   973     "set/clear the ignoreReselect flag - 
  1864 				 character and perform the click-action
   974      if set, a click on an already selected entry is ignored.
  1865 
   975      Otherwise the notification is done, even if no
  1866 	#selectAndDoubleclick -> will select next & perform double-click action
   976      change in the selection occurs.
  1867 
   977      (for example, in browser to update a method)"
  1868 	#pass                 -> will pass key to superclass (i.e. no special treatment)
   978 
  1869 
   979     ignoreReselect := aBoolean
  1870 	nil                   -> will ignore key
   980 !
  1871 
   981 
  1872      the default (set in #initialize) is #select
   982 enable
       
   983     "enable selections"
       
   984 
       
   985     enabled := true
       
   986 !
       
   987 
       
   988 disable
       
   989     "disable selections"
       
   990 
       
   991     enabled := false
       
   992 !
       
   993 
       
   994 selectionValue
       
   995     "return the selection value i.e. the text in the selected line.
       
   996      For multiple selections a collection containing the entries is returned."
       
   997 
       
   998     selection isNil ifTrue:[^ nil].
       
   999     (selection isCollection) ifTrue:[
       
  1000 	^ selection collect:[:nr | self at:nr]
       
  1001     ].
       
  1002     ^ self at:selection
       
  1003 
       
  1004 !
       
  1005 
       
  1006 numberOfSelections
       
  1007     "return the number of selected entries"
       
  1008 
       
  1009     |sz|
       
  1010 
       
  1011     selection isNil ifTrue:[^ 0].
       
  1012     sz := selection size.
       
  1013     sz > 0 ifTrue:[^ sz].
       
  1014     ^ 1
       
  1015 !
       
  1016 
       
  1017 hasSelection
       
  1018     "return true, if the view has a selection"
       
  1019 
       
  1020     ^ selection notNil 
       
  1021 !
       
  1022 
       
  1023 deselectWithoutRedraw
       
  1024     "deselect - no redraw"
       
  1025 
       
  1026     selection := nil
       
  1027 !
       
  1028 
       
  1029 deselect
       
  1030     "deselect"
       
  1031 
       
  1032     self selection:nil
       
  1033 !
       
  1034 
       
  1035 selectElement:anObject
       
  1036     "select the element with same printString as the argument, anObject.
       
  1037      Scroll to make the new selection visible."
       
  1038 
       
  1039     |lineNo|
       
  1040 
       
  1041     list notNil ifTrue:[
       
  1042 	lineNo := list indexOf:(anObject printString) ifAbsent:[].
       
  1043 	lineNo notNil ifTrue:[self selection:lineNo]
       
  1044     ]
       
  1045 !
       
  1046 
       
  1047 valueIsInSelection:someString
       
  1048     "return true, if someString is in the selection"
       
  1049 
       
  1050     |sel|
       
  1051 
       
  1052     selection isNil ifTrue:[^ false].
       
  1053     sel := self selectionValue.
       
  1054     self numberOfSelections > 1 ifTrue:[
       
  1055 	^ (sel includes:someString)
       
  1056     ].
       
  1057     ^ (someString = sel)
       
  1058 !
       
  1059 
       
  1060 selectElementWithoutScroll:anObject
       
  1061     "select the element with same printString as the argument, anObject.
       
  1062      Do not scroll."
       
  1063 
       
  1064     |lineNo|
       
  1065 
       
  1066     list notNil ifTrue:[
       
  1067 	lineNo := list indexOf:(anObject printString) ifAbsent:[].
       
  1068 	lineNo notNil ifTrue:[self selectWithoutScroll:lineNo]
       
  1069     ]
       
  1070 !
       
  1071 
       
  1072 selectAll
       
  1073     "select all entries."
       
  1074 
       
  1075     |oldSelection|
       
  1076 
       
  1077     oldSelection := selection.
       
  1078     selection := OrderedCollection withAll:(1 to:self size).
       
  1079     shown ifTrue:[self redraw].
       
  1080     self selectionChangedFrom:oldSelection.
       
  1081 !
       
  1082 
       
  1083 addElementToSelection:anObject
       
  1084     "add the element with the same printstring as the argument, anObject
       
  1085      to the selection. The entry is searched by comparing printStrings.
       
  1086      No scrolling is done. Returns true, if ok, false if no such entry
       
  1087      was found."
       
  1088 
       
  1089     |lineNo str|
       
  1090 
       
  1091     str := anObject printString.
       
  1092     lineNo := list findFirst:[:entry | str = entry printString].
       
  1093     lineNo ~~ 0 ifTrue:[
       
  1094 	self addToSelection:lineNo.
       
  1095 	^ true
       
  1096     ].
       
  1097     ^ false
       
  1098 !
       
  1099 
       
  1100 addToSelection:aNumber
       
  1101     "add entry, aNumber to the selection. No scrolling is done."
       
  1102 
       
  1103     (self isValidSelection:aNumber) ifFalse:[^ self].
       
  1104 
       
  1105     selection isNil ifTrue:[^ self selectWithoutScroll:aNumber].
       
  1106     selection isCollection ifTrue:[
       
  1107 	(selection includes:aNumber) ifTrue:[^ self].
       
  1108 	(selectConditionBlock notNil 
       
  1109 		     and:[(selectConditionBlock value:aNumber) not]) ifTrue:[^ self].
       
  1110 	selection add:aNumber
       
  1111     ] ifFalse:[
       
  1112 	(aNumber == selection) ifTrue:[^ self].
       
  1113 	(selectConditionBlock notNil 
       
  1114 		     and:[(selectConditionBlock value:aNumber) not]) ifTrue:[^ self].
       
  1115 	selection := OrderedCollection with:selection with:aNumber
       
  1116     ].
       
  1117     self redrawElement:aNumber
       
  1118 !
       
  1119 
       
  1120 removeFromSelection:aNumber
       
  1121     "remove entry, aNumber from the selection."
       
  1122 
       
  1123     selection isNil ifTrue:[^ self].
       
  1124 
       
  1125     selection isCollection ifTrue:[
       
  1126 	(selection includes:aNumber) ifFalse:[^ self].
       
  1127 	selection remove:aNumber.
       
  1128 	selection size == 1 ifTrue:[
       
  1129 	    selection := selection first
       
  1130 	] ifFalse:[
       
  1131 	    selection size == 0 ifTrue:[
       
  1132 		selection := nil
       
  1133 	    ]
       
  1134 	]
       
  1135     ] ifFalse:[
       
  1136 	(aNumber == selection) ifFalse:[^ self].
       
  1137 	selection := nil
       
  1138     ].
       
  1139     self redrawElement:aNumber
       
  1140 !
       
  1141 
       
  1142 nextAfterSelection
       
  1143     "return the number of the next selectable entry after the selection.
       
  1144      Wrap at end."
       
  1145 
       
  1146     |next|
       
  1147 
       
  1148     selection isNil ifTrue:[
       
  1149 	next := firstLineShown
       
  1150     ] ifFalse:[
       
  1151 	selection size ~~ 0 ifTrue:[
       
  1152 	    next := selection max + 1
       
  1153 	] ifFalse:[
       
  1154 	    next := selection + 1
       
  1155 	].
       
  1156     ].
       
  1157     (self isValidSelection:next) ifFalse:[
       
  1158 	next > self size ifTrue:[
       
  1159 	    next := 1.
       
  1160 	] ifFalse:[
       
  1161 	    [next <= self size
       
  1162 	     and:[(self isValidSelection:next) not]] whileTrue:[
       
  1163 		next := next + 1
       
  1164 	    ].
       
  1165 	].
       
  1166     ].
       
  1167     (self isValidSelection:next) ifFalse:[
       
  1168 	next := nil
       
  1169     ].
       
  1170     ^ next
       
  1171 !
       
  1172 
       
  1173 previousBeforeSelection
       
  1174     "return the number of the previous selectable entry before the selection.
       
  1175      Wrap at beginning."
       
  1176 
       
  1177     |prev|
       
  1178 
       
  1179     selection isNil ifTrue:[
       
  1180 	prev := firstLineShown - 1 
       
  1181     ] ifFalse:[
       
  1182 	selection size ~~ 0 ifTrue:[
       
  1183 	    prev := selection min - 1
       
  1184 	] ifFalse:[
       
  1185 	    prev := selection - 1
       
  1186 	].
       
  1187     ].
       
  1188     (self isValidSelection:prev) ifFalse:[
       
  1189 	prev < 1 ifTrue:[
       
  1190 	    prev := self size.
       
  1191 	] ifFalse:[
       
  1192 	    [prev >= 1
       
  1193 	     and:[(self isValidSelection:prev) not]] whileTrue:[
       
  1194 		prev := prev - 1
       
  1195 	    ].
       
  1196 	].
       
  1197     ].
       
  1198     (self isValidSelection:prev) ifFalse:[
       
  1199 	prev := nil
       
  1200     ].
       
  1201     ^ prev
       
  1202 
       
  1203 !
       
  1204 
       
  1205 toggleSelection:aNumber
       
  1206     "toggle selection-state of entry, aNumber"
       
  1207 
       
  1208     (self isInSelection:aNumber) ifTrue:[
       
  1209 	self removeFromSelection:aNumber
       
  1210     ] ifFalse:[
       
  1211 	self addToSelection:aNumber
       
  1212     ]
       
  1213 !
       
  1214 
       
  1215 selectNext
       
  1216     "select next line or first visible if there is currrently no selection.
       
  1217      Wrap at end."
       
  1218 
       
  1219     self selection:(self nextAfterSelection)
       
  1220 !
       
  1221 
       
  1222 selectPrevious
       
  1223     "select previous line or previous visible if there is currently no selection.
       
  1224      Wrap at beginning."
       
  1225 
       
  1226     self selection:(self previouseBeforeSelection).
       
  1227 !
       
  1228 
       
  1229 selectionDo:aBlock
       
  1230     "perform aBlock for each nr in the selection.
       
  1231      For single selection, it is called once for the items nr.
       
  1232      For multiple selections, it is called for each."
       
  1233 
       
  1234     |sz|
       
  1235 
       
  1236     selection isNil ifTrue:[^ self].
       
  1237     sz := selection size.
       
  1238     sz > 0 ifTrue:[
       
  1239 	selection do:aBlock
       
  1240     ] ifFalse:[
       
  1241 	aBlock value:selection
       
  1242     ].
       
  1243 !
       
  1244 
       
  1245 argForChangeMessage
       
  1246     "return the argument for a selectionChange;
       
  1247      depending on the setting of useIndex, this is either the numeric
       
  1248      index of the selection or the value (i.e. the string)"
       
  1249 
       
  1250     useIndex == false ifTrue:[
       
  1251 	printItems ifFalse:[
       
  1252 	    ^ self selectionValue
       
  1253 	].
       
  1254 	^ items at:selection
       
  1255     ].
       
  1256     "true or nil - strange"
       
  1257     ^ selection.
       
  1258 !
       
  1259 
       
  1260 selectionChangedFrom:oldSelection
       
  1261     "selection has changed. Call actionblock and/or send changeMessage if defined"
       
  1262 
       
  1263     |arg|
       
  1264 
       
  1265     arg := self argForChangeMessage.
       
  1266     "
  1873     "
  1267      the ST/X way of doing things - perform actionBlock
  1874 
       
  1875     keyActionStyle := aSymbol
       
  1876 !
       
  1877 
       
  1878 returnKeyActionStyle:aSymbol
       
  1879     "defines how the view should respond to a return key pressed.
       
  1880      Possible values are:
       
  1881 	#doubleClick          -> perform double-click action
       
  1882 
       
  1883 	#pass                 -> will pass key to superclass (i.e. no special treatment)
       
  1884 
       
  1885 	nil                   -> will ignore key
       
  1886 
       
  1887      the default (set in #initialize) is #doubleClick 
  1268     "
  1888     "
  1269     actionBlock notNil ifTrue:[actionBlock value:arg].
  1889 
  1270     "
  1890     returnKeyActionStyle := aSymbol
  1271      the ST-80 way of doing things - notify model via changeMsg
       
  1272     "
       
  1273     "/ ST80 sends 0 as index, if the same selection is reselected ...
       
  1274     selection == oldSelection ifTrue:[
       
  1275 	arg := 0
       
  1276     ].
       
  1277     self sendChangeMessageWith:arg
       
  1278 !
       
  1279 
       
  1280 selectionAsCollection
       
  1281     "return the selection as a collection of line numbers"
       
  1282 
       
  1283     selection size = 0 ifTrue:[
       
  1284 	selection isNil ifTrue:[^ #()].
       
  1285 	 ^ (OrderedCollection new) add:selection; yourself.
       
  1286     ] ifFalse:[
       
  1287 	 ^ selection
       
  1288     ].
       
  1289 ! !
  1891 ! !
  1290 
  1892 
  1291 !SelectionInListView methodsFor:'accessing'!
  1893 !SelectionInListView methodsFor:'accessing-attributes'!
  1292 
  1894 
  1293 line:lineNr hasAttribute:aSymbol
  1895 line:lineNr hasAttribute:aSymbol
  1294     "return true, if line nr has attribute, aSymbol; 
  1896     "return true, if line nr has attribute, aSymbol; 
  1295      currently supported attributes are:
  1897      currently supported attributes are:
  1296 	 #halfIntensity
  1898 	 #halfIntensity
  1298 	 #bold 
  1900 	 #bold 
  1299     "
  1901     "
  1300 
  1902 
  1301     |attr|
  1903     |attr|
  1302 
  1904 
       
  1905     listAttributes isNil ifTrue:[^ false].
  1303     (lineNr > listAttributes size) ifTrue:[^ false].
  1906     (lineNr > listAttributes size) ifTrue:[^ false].
  1304     attr := listAttributes at:lineNr.
  1907     attr := listAttributes at:lineNr.
  1305     attr isNil ifTrue:[^ false].
  1908     attr isNil ifTrue:[^ false].
  1306     attr isSymbol ifTrue:[^ attr == aSymbol].
  1909     attr isSymbol ifTrue:[^ attr == aSymbol].
  1307     ^ (attr includes:aSymbol)
  1910     ^ (attr includes:aSymbol)
  1308 !
  1911 !
  1309 
  1912 
  1310 contents:aCollection
  1913 setAttributes:aList
  1311     "set the list - redefined, since setting the list implies unselecting
  1914     "set the attribute list.
  1312      and clearing attributes."
  1915      No redraw is done - the caller should make sure to redraw afterwards
  1313 
  1916      (or use this only before the view is visible)."
  1314     selection := nil.
  1917 
  1315     listAttributes := nil.
  1918     listAttributes := aList
  1316     super contents:aCollection.
       
  1317 !
  1919 !
  1318 
  1920 
  1319 attributeAt:index put:aSymbolOrCollectionOfSymbolsOrNil
  1921 attributeAt:index put:aSymbolOrCollectionOfSymbolsOrNil
  1320     "set a lines attribute(s); 
  1922     "set a lines attribute(s); 
  1321      currently supported are:
  1923      currently supported are:
  1338 	]
  1940 	]
  1339     ]
  1941     ]
  1340 
  1942 
  1341 !
  1943 !
  1342 
  1944 
  1343 setList:aCollection
  1945 strikeOut:aBoolean
  1344     "set the list - redefined, since setting the list implies unselecting
  1946     "turn on/off strikeOut mode"
  1345      and clearing attributes.
  1947 
  1346      No redraw is done - the caller should make sure to redraw afterwards
  1948     strikeOut := aBoolean.
  1347      (or use this only before the view is visible)."
       
  1348 
       
  1349     selection := nil.
       
  1350     listAttributes := nil.
       
  1351     super setList:aCollection.
       
  1352 !
       
  1353 
       
  1354 list:aCollection
       
  1355     "set the list - redefined, since setting the list implies unselecting
       
  1356      and clearing attributes."
       
  1357 
       
  1358     "somewhat of a kludge: if selection is first line,
       
  1359      we have to remove the highlight frame by hand here"
       
  1360 
       
  1361     (shown and:[hilightLevel ~~ 0]) ifTrue:[
       
  1362 	selection == firstLineShown ifTrue:[
       
  1363 	   self paint:bgColor.
       
  1364 	   self fillRectangleX:margin y:margin
       
  1365 			  width:(width - (margin * 2)) 
       
  1366 			 height:(hilightLevel abs).
       
  1367 	].
       
  1368     ].
       
  1369 
       
  1370     selection := nil.
       
  1371     listAttributes := nil.
       
  1372     super list:aCollection.
       
  1373 !
       
  1374 
       
  1375 setAttributes:aList
       
  1376     "set the attribute list.
       
  1377      No redraw is done - the caller should make sure to redraw afterwards
       
  1378      (or use this only before the view is visible)."
       
  1379 
       
  1380     listAttributes := aList
       
  1381 !
       
  1382 
       
  1383 keyActionStyle:aSymbol
       
  1384     "defines how the view should respond to alpha-keys pressed.
       
  1385      Possible values are:
       
  1386 	#select               -> will select next entry starting with that
       
  1387 				 character and perform the click-action
       
  1388 
       
  1389 	#selectAndDoubleclick -> will select next & perform double-click action
       
  1390 
       
  1391 	#pass                 -> will pass key to superclass (i.e. no special treatment)
       
  1392 
       
  1393 	nil                   -> will ignore key
       
  1394 
       
  1395      the default (set in #initialize) is #select
       
  1396     "
       
  1397 
       
  1398     keyActionStyle := aSymbol
       
  1399 !
  1949 !
  1400 
  1950 
  1401 attributeAt:index
  1951 attributeAt:index
  1402     "return the line attribute of list line index.
  1952     "return the line attribute of list line index.
  1403      currently supported are:
  1953      currently supported are:
  1410 	(index > listAttributes size) ifFalse:[
  1960 	(index > listAttributes size) ifFalse:[
  1411 	    ^ listAttributes at:index
  1961 	    ^ listAttributes at:index
  1412 	]
  1962 	]
  1413     ].
  1963     ].
  1414     ^ nil
  1964     ^ nil
  1415 !
       
  1416 
       
  1417 action:aBlock
       
  1418     "set the action block to be performed on select"
       
  1419 
       
  1420     actionBlock := aBlock
       
  1421 !
  1965 !
  1422 
  1966 
  1423 attributeAt:index add:aSymbolOrCollectionOfSymbols
  1967 attributeAt:index add:aSymbolOrCollectionOfSymbols
  1424     "add to a lines attribute(s); 
  1968     "add to a lines attribute(s); 
  1425      currently supported are:
  1969      currently supported are:
  1445     ] ifFalse:[
  1989     ] ifFalse:[
  1446 	(current includes:aSymbolOrCollectionOfSymbols) ifTrue:[^ self].
  1990 	(current includes:aSymbolOrCollectionOfSymbols) ifTrue:[^ self].
  1447 	current addAll:aSymbolOrCollectionOfSymbols
  1991 	current addAll:aSymbolOrCollectionOfSymbols
  1448     ].
  1992     ].
  1449     self attributeAt:index put:current
  1993     self attributeAt:index put:current
  1450 !
       
  1451 
       
  1452 doubleClickAction:aBlock
       
  1453     "set the double click action block to be performed on select"
       
  1454 
       
  1455     doubleClickActionBlock := aBlock
       
  1456 !
  1994 !
  1457 
  1995 
  1458 attributeAt:index remove:aSymbolOrCollectionOfSymbols
  1996 attributeAt:index remove:aSymbolOrCollectionOfSymbols
  1459     "remove a line attribute; 
  1997     "remove a line attribute; 
  1460      currently supported are:
  1998      currently supported are:
  1481 	] ifFalse:[
  2019 	] ifFalse:[
  1482 	    aSymbolOrCollectionOfSymbols removeAll:aSymbolOrCollectionOfSymbols
  2020 	    aSymbolOrCollectionOfSymbols removeAll:aSymbolOrCollectionOfSymbols
  1483 	]
  2021 	]
  1484     ].
  2022     ].
  1485     self attributeAt:index put:current
  2023     self attributeAt:index put:current
       
  2024 ! !
       
  2025 
       
  2026 !SelectionInListView methodsFor:'accessing-behavior'!
       
  2027 
       
  2028 ignoreReselect:aBoolean
       
  2029     "set/clear the ignoreReselect flag - 
       
  2030      if set, a click on an already selected entry is ignored.
       
  2031      Otherwise the notification is done, even if no
       
  2032      change in the selection occurs.
       
  2033      (for example, in browser to update a method)"
       
  2034 
       
  2035     ignoreReselect := aBoolean
       
  2036 !
       
  2037 
       
  2038 toggleSelect:aBoolean
       
  2039     "turn on/off toggle select. If true, clicking on a selected entry
       
  2040      unselects it and vice versa. The default is false."
       
  2041 
       
  2042     toggleSelect := aBoolean.
       
  2043 !
       
  2044 
       
  2045 multipleSelectOk:aBoolean
       
  2046     "allow/disallow multiple selections"
       
  2047 
       
  2048     multipleSelectOk := aBoolean.
       
  2049     aBoolean ifTrue:[
       
  2050 	self enableButtonMotionEvents
       
  2051     ] ifFalse:[
       
  2052 	self disableButtonMotionEvents
       
  2053     ] 
       
  2054 !
       
  2055 
       
  2056 enable
       
  2057     "enable the view - selection changes are allowed"
       
  2058 
       
  2059     enabled := true
       
  2060 !
       
  2061 
       
  2062 disable
       
  2063     "disable the view - no selection changes are allowed"
       
  2064 
       
  2065     enabled := false
       
  2066 ! !
       
  2067 
       
  2068 !SelectionInListView methodsFor:'accessing-contents'!
       
  2069 
       
  2070 list:aCollection
       
  2071     "set the list - redefined, since setting the list implies unselecting
       
  2072      and clearing attributes."
       
  2073 
       
  2074     "somewhat of a kludge: if selection is first line,
       
  2075      we have to remove the highlight frame by hand here"
       
  2076 
       
  2077     (shown and:[hilightLevel ~~ 0]) ifTrue:[
       
  2078 	selection == firstLineShown ifTrue:[
       
  2079 	   self paint:bgColor.
       
  2080 	   self fillRectangleX:margin y:margin
       
  2081 			  width:(width - (margin * 2)) 
       
  2082 			 height:(hilightLevel abs).
       
  2083 	].
       
  2084     ].
       
  2085 
       
  2086     selection := nil.
       
  2087     listAttributes := nil.
       
  2088     super list:aCollection.
       
  2089 !
       
  2090 
       
  2091 setList:aCollection
       
  2092     "set the list - redefined, since setting the list implies unselecting
       
  2093      and clearing attributes.
       
  2094      No redraw is done - the caller should make sure to redraw afterwards
       
  2095      (or use this only before the view is visible)."
       
  2096 
       
  2097     selection := nil.
       
  2098     listAttributes := nil.
       
  2099     super setList:aCollection.
  1486 !
  2100 !
  1487 
  2101 
  1488 removeIndexWithoutRedraw:lineNr
  2102 removeIndexWithoutRedraw:lineNr
  1489     "delete line - no redraw;
  2103     "delete line - no redraw;
  1490      return true, if something was really deleted.
  2104      return true, if something was really deleted.
  1504 
  2118 
  1505 add:aValue beforeIndex:index
  2119 add:aValue beforeIndex:index
  1506     "must recompute our current selections"
  2120     "must recompute our current selections"
  1507 
  2121 
  1508     selection notNil ifTrue:[
  2122     selection notNil ifTrue:[
  1509 	selection size = 0 ifTrue:[
  2123 	multipleSelectOk ifTrue:[
  1510 	    selection >= index ifTrue:[
       
  1511 		selection := selection + 1.
       
  1512 	    ].
       
  1513 	] ifFalse:[
       
  1514 	    selection := selection collect:[ :sel |
  2124 	    selection := selection collect:[ :sel |
  1515 		sel >= index ifTrue:[
  2125 		sel >= index ifTrue:[
  1516 		    sel + 1
  2126 		    sel + 1
  1517 		] ifFalse:[
  2127 		] ifFalse:[
  1518 		    sel
  2128 		    sel
  1519 		]
  2129 		]
  1520 	    ].
  2130 	    ].
       
  2131 	] ifFalse:[
       
  2132 	    selection >= index ifTrue:[
       
  2133 		selection := selection + 1.
       
  2134 	    ].
  1521 	].
  2135 	].
  1522     ].
  2136     ].
  1523     ^ super add:aValue beforeIndex:index.
  2137     ^ super add:aValue beforeIndex:index.
  1524 !
       
  1525 
       
  1526 useIndex:aBoolean
       
  1527     "set/clear the useIndex flag. If set, both actionBlock and change-messages
       
  1528      are passed the index of the selection as argument. If clear, the value
       
  1529      (i.e. the selected string) is passed.
       
  1530      Default is true."
       
  1531 
       
  1532     useIndex := aBoolean
       
  1533 ! !
       
  1534 
       
  1535 !SelectionInListView methodsFor:'accessing-mvc'!
       
  1536 
       
  1537 on:aModel printItems:print oneItem:one aspect:aspectSymbol change:changeSymbol 
       
  1538 		list:listSymbol menu:menuSymbol initialSelection:initialSymbol useIndex:use
       
  1539 
       
  1540     "ST-80 compatibility"
       
  1541 
       
  1542     aspectMsg := aspectSymbol.
       
  1543     changeMsg := changeSymbol.
       
  1544     listMsg := listSymbol.
       
  1545     menuMsg := menuSymbol.
       
  1546     initialSelectionMsg := initialSymbol.
       
  1547     printItems := print.
       
  1548     oneItem := one.
       
  1549     useIndex := use.
       
  1550     ignoreReselect := false.    "/ ST80 behavior
       
  1551     self model:aModel.
       
  1552 !
       
  1553 
       
  1554 doubleClickMessage
       
  1555     "return the symbol with which the model (if any) is informed about 
       
  1556      double-click. If nil (which is the default), it is not informed."
       
  1557 
       
  1558     ^ doubleClickMsg
       
  1559 !
       
  1560 
       
  1561 doubleClickMessage:aSymbol
       
  1562     "set the symbol with which the model (if any) is informed about double-click.
       
  1563      If nil (which is the default), it is not informed."
       
  1564 
       
  1565     doubleClickMsg := aSymbol
       
  1566 !
       
  1567 
       
  1568 doubleClick:aSymbol
       
  1569     "set the symbol with which the model is informed about double-click.
       
  1570      OBSOLETE: please use #doubleClickMessage:"
       
  1571 
       
  1572     self obsoleteMethodWarning:'please use #doubleClickMessage:'.
       
  1573     doubleClickMsg := aSymbol
       
  1574 !
       
  1575 
       
  1576 selectionMessage
       
  1577     "return the symbol by which the model informes me about a changed
       
  1578      selectionIndex. This is used both in change notification and to
       
  1579      actually aquire a new selection value."
       
  1580 
       
  1581     ^ initialSelectionMsg
       
  1582 !
       
  1583 
       
  1584 selectionMessage:aSymbol
       
  1585     "set the symbol by which the model informes me about a changed
       
  1586      selectionIndex. This is used both in change notification and to
       
  1587      actually aquire a new selection value."
       
  1588 
       
  1589     initialSelectionMsg := aSymbol
       
  1590 !
       
  1591 
       
  1592 addModelInterfaceTo:aDictionary
       
  1593     "see comment in View>>modelInterface"
       
  1594 
       
  1595     super addModelInterfaceTo:aDictionary.
       
  1596     aDictionary at:#doubleClickMessage put:doubleClickMsg.
       
  1597     aDictionary at:#selectionMessage put:initialSelectionMsg.
       
  1598 
       
  1599     "
       
  1600      SelectionInListView new modelInterface 
       
  1601     "
       
  1602 ! !
       
  1603 
       
  1604 !SelectionInListView methodsFor:'private'!
       
  1605 
       
  1606 isValidSelection:aNumber
       
  1607     "return true, if aNumber is ok for a selection lineNo"
       
  1608 
       
  1609     aNumber isNil ifTrue:[^ false].
       
  1610     (aNumber isCollection) ifTrue:[
       
  1611 	(multipleSelectOk or:[aNumber size = 1]) ifFalse:[^ false].
       
  1612 	aNumber do:[ :line |
       
  1613 	    (line between:1 and:self size) ifFalse:[^ false].
       
  1614 	].
       
  1615 	^ true.
       
  1616     ] ifFalse:[
       
  1617 	^ (aNumber between:1 and:self size).
       
  1618     ].
       
  1619 
       
  1620 !
       
  1621 
       
  1622 widthForScrollBetween:start and:end
       
  1623     "has to be redefined since WHOLE line is inverted/modified sometimes"
       
  1624 
       
  1625     | anySelectionInRange |
       
  1626 
       
  1627     selection notNil ifTrue:[
       
  1628 	selection isCollection ifTrue:[
       
  1629 	    anySelectionInRange := false.
       
  1630 	    selection do:[:s |
       
  1631 		(s between:start and:end) ifTrue:[
       
  1632 		    anySelectionInRange := true
       
  1633 		]
       
  1634 	    ]
       
  1635 	] ifFalse:[
       
  1636 	    anySelectionInRange := selection between:start and:end
       
  1637 	]
       
  1638     ] ifFalse:[
       
  1639 	anySelectionInRange := false
       
  1640     ].
       
  1641 
       
  1642     anySelectionInRange ifTrue:[
       
  1643 	^ width
       
  1644 "
       
  1645 	self is3D ifFalse:[
       
  1646 	    ^ width 
       
  1647 	].
       
  1648 	( #(next openwin) includes:style) ifTrue:[
       
  1649 	    ^ width 
       
  1650 	].
       
  1651 	viewBackground = background ifFalse:[
       
  1652 	    ^ width 
       
  1653 	]
       
  1654 "
       
  1655     ].
       
  1656     ^ super widthForScrollBetween:start and:end
       
  1657 !
       
  1658 
       
  1659 positionToSelectionX:x y:y
       
  1660     "given a click position, return the selection lineNo"
       
  1661 
       
  1662     |visibleLine|
       
  1663 
       
  1664     (x between:0 and:width) ifTrue:[
       
  1665 	(y between:0 and:height) ifTrue:[
       
  1666 	    visibleLine := self visibleLineOfY:y.
       
  1667 	    ^ self visibleLineToListLine:visibleLine
       
  1668 	]
       
  1669     ].
       
  1670     ^ nil
       
  1671 !
       
  1672 
       
  1673 visibleLineNeedsSpecialCare:visLineNr
       
  1674     |listLine|
       
  1675 
       
  1676     listLine := self visibleLineToListLine:visLineNr.
       
  1677     listLine isNil ifTrue:[^ false].
       
  1678     (self isInSelection:listLine) ifTrue:[^ true].
       
  1679     listAttributes notNil ifTrue:[
       
  1680 	(listLine <= listAttributes size) ifTrue:[
       
  1681 	    ^ (listAttributes at:listLine) notNil
       
  1682 	]
       
  1683     ].
       
  1684     ^ false
       
  1685 !
       
  1686 
       
  1687 checkRemovingSelection:lineNr
       
  1688     "when a line is removed, we have to adjust selection"
       
  1689 
       
  1690     |newSelection|
       
  1691 
       
  1692     selection notNil ifTrue:[
       
  1693 	(selection size > 0) ifTrue:[
       
  1694 	    newSelection := OrderedCollection new.
       
  1695 	    selection do:[:sel |
       
  1696 		sel < lineNr ifTrue:[
       
  1697 		    newSelection add:sel
       
  1698 		] ifFalse:[
       
  1699 		    sel > lineNr ifTrue:[
       
  1700 			newSelection add:(sel - 1)
       
  1701 		    ]
       
  1702 		    "otherwise remove it from the selection"
       
  1703 		]
       
  1704 	    ].
       
  1705 	    newSelection size == 1 ifTrue:[
       
  1706 		selection := newSelection first
       
  1707 	    ] ifFalse:[
       
  1708 		newSelection size == 0 ifTrue:[
       
  1709 		    selection := nil
       
  1710 		] ifFalse:[
       
  1711 		    selection := newSelection
       
  1712 		]
       
  1713 	    ]
       
  1714 	] ifFalse:[
       
  1715 	    selection == lineNr ifTrue:[
       
  1716 		selection := nil
       
  1717 	    ] ifFalse:[
       
  1718 		selection > lineNr ifTrue:[
       
  1719 		    selection := selection - 1
       
  1720 		]
       
  1721 	    ]
       
  1722 	]
       
  1723     ]
       
  1724 !
       
  1725 
       
  1726 scrollSelectDown
       
  1727     "auto scroll action; scroll and reinstall timed-block"
       
  1728 
       
  1729     self scrollDown.
       
  1730     Processor addTimedBlock:autoScrollBlock afterSeconds:autoScrollDeltaT.
       
  1731 !
       
  1732 
       
  1733 scrollSelectUp
       
  1734     "auto scroll action; scroll and reinstall timed-block"
       
  1735 
       
  1736     self scrollUp.
       
  1737     Processor addTimedBlock:autoScrollBlock afterSeconds:autoScrollDeltaT.
       
  1738 !
       
  1739 
       
  1740 getListFromModel
       
  1741     "if I have a model and a listMsg, get my list from it"
       
  1742 
       
  1743     |text|
       
  1744 
       
  1745     model notNil ifTrue:[
       
  1746 	listMsg notNil ifTrue:[
       
  1747 	    items := model perform:listMsg.
       
  1748 	    items notNil ifTrue:[
       
  1749 		printItems ifTrue:[
       
  1750 		    text := items collect:[:element | element printString]
       
  1751 		] ifFalse:[
       
  1752 		    text := items
       
  1753 		].
       
  1754 		text notNil ifTrue:[
       
  1755 		    text := text asStringCollection.
       
  1756 		]
       
  1757 	    ].
       
  1758 	    self list:text
       
  1759 	].
       
  1760     ].
       
  1761 !
       
  1762 
       
  1763 getSelectionFromModel
       
  1764     "if I have a model and an initialSelectionMsg, get my selection from it"
       
  1765 
       
  1766     |sel|
       
  1767 
       
  1768     model notNil ifTrue:[
       
  1769 	initialSelectionMsg notNil ifTrue:[
       
  1770 	    sel := model perform:initialSelectionMsg.
       
  1771 	    useIndex ifTrue:[
       
  1772 		self selection:sel 
       
  1773 	    ] ifFalse:[
       
  1774 		self selectElement:sel.
       
  1775 	    ].
       
  1776 	]
       
  1777     ].
       
  1778 ! !
  2138 ! !
  1779 
  2139 
  1780 !SelectionInListView methodsFor:'initialization'!
  2140 !SelectionInListView methodsFor:'initialization'!
  1781 
  2141 
  1782 initCursor
  2142 initCursor
  1783     "set the cursor - a hand"
  2143     "set the cursor - a hand"
  1784 
  2144 
  1785     cursor := Cursor hand
  2145     cursor := Cursor hand
  1786 !
  2146 !
  1787 
  2147 
       
  2148 initialize
       
  2149     super initialize.
       
  2150 
       
  2151     fontHeight := font height + lineSpacing.
       
  2152     enabled := true.
       
  2153     ignoreReselect := true.
       
  2154     multipleSelectOk := toggleSelect := strikeOut := printItems := false.
       
  2155     useIndex := true.
       
  2156 
       
  2157     keyActionStyle := #select.
       
  2158     returnKeyActionStyle := #doubleClick.
       
  2159 
       
  2160     listMsg := self class defaultListMessage.
       
  2161     initialSelectionMsg := self class defaultSelectionMessage.
       
  2162 
       
  2163 !
       
  2164 
  1788 realize
  2165 realize
  1789     super realize.
  2166     super realize.
  1790 
  2167 
       
  2168     self getListFromModel.
       
  2169     self getSelectionFromModel.
       
  2170 
  1791     selection notNil ifTrue:[
  2171     selection notNil ifTrue:[
  1792 	self makeLineVisible:selection
  2172 	self makeLineVisible:selection
  1793     ].
  2173     ].
  1794     self getListFromModel.
       
  1795     self getSelectionFromModel
       
  1796 !
       
  1797 
       
  1798 initialize
       
  1799     super initialize.
       
  1800 
       
  1801     fontHeight := font height + lineSpacing.
       
  1802     enabled := true.
       
  1803     multipleSelectOk := false.
       
  1804     ignoreReselect := true.
       
  1805     toggleSelect := false.
       
  1806     strikeOut := false.
       
  1807     keyActionStyle := #select.
       
  1808 !
  2174 !
  1809 
  2175 
  1810 initStyle
  2176 initStyle
  1811     |nm|
  2177     |nm|
  1812 
  2178 
  1906     hilightFrameColor notNil ifTrue:[hilightFrameColor := hilightFrameColor on:device].
  2272     hilightFrameColor notNil ifTrue:[hilightFrameColor := hilightFrameColor on:device].
  1907     hilightFgColor := hilightFgColor on:device.
  2273     hilightFgColor := hilightFgColor on:device.
  1908     hilightBgColor := hilightBgColor on:device.
  2274     hilightBgColor := hilightBgColor on:device.
  1909 ! !
  2275 ! !
  1910 
  2276 
  1911 !SelectionInListView methodsFor:'event handling'!
  2277 !SelectionInListView methodsFor:'change & update'!
  1912 
  2278 
  1913 buttonPress:button x:x y:y
  2279 update:something with:aParameter from:changedObject
  1914     |oldSelection listLineNr|
  2280     changedObject == model ifTrue:[
  1915 
  2281         something == aspectMsg ifTrue:[
  1916     ((button == 1) or:[button == #select]) ifTrue:[
  2282             self getListFromModel.
  1917 	enabled ifTrue:[
  2283             self getSelectionFromModel.
  1918 	    listLineNr := self visibleLineToListLine:(self visibleLineOfY:y).
  2284             ^ self
  1919 	    listLineNr notNil ifTrue:[
  2285         ].
  1920 		(toggleSelect 
  2286         something == listMsg ifTrue:[
  1921 		and:[self isInSelection:listLineNr]) ifTrue:[
  2287             self getListFromModel.
  1922 		    oldSelection := selection copy.
  2288             ^ self
  1923 		    self removeFromSelection:listLineNr
  2289         ].
  1924 		] ifFalse:[
  2290         something == initialSelectionMsg ifTrue:[
  1925 		    (self line:listLineNr hasAttribute:#disabled) ifTrue:[^ self].
  2291             self getSelectionFromModel.
  1926 
  2292             ^ self
  1927 		    (selectConditionBlock notNil 
  2293         ].
  1928 		     and:[(selectConditionBlock value:listLineNr) not]) ifTrue:[^ self].
  2294         something == #empty ifTrue:[
  1929 
  2295             self list:nil.
  1930 		    (toggleSelect and:[multipleSelectOk]) ifTrue:[
  2296             ^ self
  1931 			oldSelection := selection copy.
  2297         ].
  1932 			self addToSelection:listLineNr
  2298     ].
  1933 		    ] ifFalse:[
  2299     ^ super update:something with:aParameter from:changedObject
  1934 			oldSelection := selection copy.
  2300 ! !
  1935 			self selectWithoutScroll:listLineNr.
  2301 
  1936 		    ].
  2302 !SelectionInListView methodsFor:'accessing-selection'!
  1937 		].
  2303 
  1938 		((ignoreReselect not and:[selection notNil])
  2304 addToSelection:aNumber
  1939 		 or:[selection ~= oldSelection]) ifTrue:[
  2305     "add entry, aNumber to the selection. No scrolling is done."
  1940 		    self selectionChangedFrom:oldSelection.
  2306 
  1941 		].
  2307     (self isValidSelection:aNumber) ifFalse:[^ self].
  1942 		clickLine := listLineNr
  2308 
  1943 	    ].
  2309     selection isNil ifTrue:[^ self selectWithoutScroll:aNumber].
       
  2310     selection isCollection ifTrue:[
       
  2311 	(selection includes:aNumber) ifTrue:[^ self].
       
  2312 	(selectConditionBlock notNil 
       
  2313 		     and:[(selectConditionBlock value:aNumber) not]) ifTrue:[^ self].
       
  2314 	selection add:aNumber
       
  2315     ] ifFalse:[
       
  2316 	(aNumber == selection) ifTrue:[^ self].
       
  2317 	(selectConditionBlock notNil 
       
  2318 		     and:[(selectConditionBlock value:aNumber) not]) ifTrue:[^ self].
       
  2319 	selection := OrderedCollection with:selection with:aNumber
       
  2320     ].
       
  2321     self redrawElement:aNumber
       
  2322 !
       
  2323 
       
  2324 addElementToSelection:anObject
       
  2325     "add the element with the same printstring as the argument, anObject
       
  2326      to the selection. The entry is searched by comparing printStrings.
       
  2327      No scrolling is done. Returns true, if ok, false if no such entry
       
  2328      was found."
       
  2329 
       
  2330     |lineNo str|
       
  2331 
       
  2332     str := anObject printString.
       
  2333     lineNo := list findFirst:[:entry | str = entry printString].
       
  2334     lineNo ~~ 0 ifTrue:[
       
  2335 	self addToSelection:lineNo.
       
  2336 	^ true
       
  2337     ].
       
  2338     ^ false
       
  2339 !
       
  2340 
       
  2341 removeFromSelection:aNumber
       
  2342     "remove entry, aNumber from the selection."
       
  2343 
       
  2344     selection isNil ifTrue:[^ self].
       
  2345 
       
  2346     multipleSelectOk ifTrue:[
       
  2347 	(selection includes:aNumber) ifFalse:[^ self].
       
  2348 	selection remove:aNumber.
       
  2349 	selection size == 0 ifTrue:[
       
  2350 	    selection := nil
  1944 	]
  2351 	]
  1945     ] ifFalse:[
  2352     ] ifFalse:[
  1946 	super buttonPress:button x:x y:y
  2353 	(aNumber == selection) ifFalse:[^ self].
  1947     ]
  2354 	selection := nil
  1948 !
  2355     ].
  1949 
  2356     self redrawElement:aNumber
  1950 sizeChanged:how
  2357 ! !
  1951     "if there is a selection, make certain, its visible
  2358 
  1952      after the sizechange"
  2359 !SelectionInListView methodsFor:'accessing-mvc'!
  1953 
  2360 
  1954     |first wasAtEnd|
  2361 on:aModel printItems:print oneItem:one aspect:aspectSymbol change:changeSymbol 
  1955 
  2362 		list:listSymbol menu:menuSymbol initialSelection:initialSymbol useIndex:use
  1956     wasAtEnd := (firstLineShown + nFullLinesShown) >= self size.
  2363 
  1957 
  2364     "ST-80 compatibility"
  1958     super sizeChanged:how.
  2365 
  1959 
  2366     aspectMsg := aspectSymbol.
  1960     shown ifTrue:[
  2367     changeMsg := changeSymbol.
  1961 	selection notNil ifTrue:[
  2368     listMsg := listSymbol.
  1962 	    selection isCollection ifTrue:[
  2369     menuMsg := menuSymbol.
  1963 		selection notEmpty ifTrue:[
  2370     initialSelectionMsg := initialSymbol.
  1964 		    first := selection first
  2371     printItems := print.
  1965 		]
  2372     oneItem := one.
  1966 	    ] ifFalse:[
  2373     useIndex := use.
  1967 		first := selection
  2374     ignoreReselect := false.    "/ ST80 behavior
  1968 	    ].
  2375     self model:aModel.
  1969 	    first notNil ifTrue:[self makeLineVisible:first]
  2376 !
  1970 	] ifFalse:[
  2377 
  1971 	    "
  2378 doubleClickMessage
  1972 	     if we where at the end before, move to the end again.
  2379     "return the symbol with which the model (if any) is informed about 
  1973 	     Still to be seen, if this is better in real life ...
  2380      double-click. If nil (which is the default), it is not informed."
  1974 	    "
  2381 
  1975 	    wasAtEnd ifTrue:[
  2382     ^ doubleClickMsg
  1976 		"at end"
  2383 !
  1977 		self scrollToBottom
  2384 
  1978 	    ]
  2385 doubleClickMessage:aSymbol
  1979 	]
  2386     "set the symbol with which the model (if any) is informed about double-click.
  1980     ]
  2387      If nil (which is the default), it is not informed."
  1981 !
  2388 
  1982 
  2389     doubleClickMsg := aSymbol
  1983 buttonRelease:button x:x y:y
  2390 !
  1984     "stop any autoscroll"
  2391 
  1985 
  2392 doubleClick:aSymbol
  1986     self stopAutoScroll
  2393     "set the symbol with which the model is informed about double-click.
  1987 !
  2394      OBSOLETE: please use #doubleClickMessage:"
  1988 
  2395 
  1989 key:key select:selectAction x:x y:y
  2396     self obsoleteMethodWarning:'please use #doubleClickMessage:'.
  1990     "perform keyaction after a key-select"
  2397     doubleClickMsg := aSymbol
  1991 
  2398 !
  1992     |oldSelection|
  2399 
  1993 
  2400 initialSelectionMessage
  1994     keyActionStyle notNil ifTrue:[
  2401     "return the symbol by which the model informes me about a changed
  1995 	keyActionStyle == #pass ifTrue:[
  2402      selectionIndex. This is used both in change notification and to
  1996 	    ^ super keyPress:key x:x y:y
  2403      actually aquire a new selection value."
  1997 	].
  2404 
  1998 	oldSelection := selection.
  2405     ^ initialSelectionMsg
  1999 	selectAction value.
  2406 !
  2000 	self selectionChangedFrom:oldSelection.
  2407 
  2001 	keyActionStyle == #selectAndDoubleClick ifTrue:[
  2408 initialSelectionMessage:aSymbol
  2002 	    doubleClickActionBlock notNil ifTrue:[doubleClickActionBlock value:selection].
  2409     "set the symbol by which the model informes me about a changed
  2003 	]
  2410      selectionIndex. This is used both in change notification and to
  2004     ].
  2411      actually aquire a new selection value."
  2005 !
  2412 
  2006 
  2413     initialSelectionMsg := aSymbol
  2007 keyPress:key x:x y:y
  2414 !
  2008     "handle keyboard input"
  2415 
  2009 
  2416 addModelInterfaceTo:aDictionary
  2010     |index startSearch backSearch searchPrefix|
  2417     "see comment in View>>modelInterface"
  2011 
  2418 
  2012     (key == #CursorUp) ifTrue:[
  2419     super addModelInterfaceTo:aDictionary.
  2013 	index := self previousBeforeSelection.
  2420     aDictionary at:#doubleClickMessage put:doubleClickMsg.
  2014 	(selectConditionBlock isNil or:[selectConditionBlock value:index]) ifTrue:[
  2421     aDictionary at:#initialSelectionMessage put:initialSelectionMsg.
  2015 	    self key:key select:[self selection:index] x:x y:y
  2422 
  2016 	].
       
  2017 	^ self
       
  2018     ].
       
  2019     (key == #CursorDown) ifTrue:[
       
  2020 	index := self nextAfterSelection.
       
  2021 	(selectConditionBlock isNil or:[selectConditionBlock value:index]) ifTrue:[
       
  2022 	    self key:key select:[self selection:index] x:x y:y
       
  2023 	].
       
  2024 	^ self
       
  2025     ].
       
  2026     (key == #Home) ifTrue:[
       
  2027 	(selectConditionBlock isNil or:[selectConditionBlock value:1]) ifTrue:[
       
  2028 	    self key:key select:[self selection:1] x:x y:y
       
  2029 	].
       
  2030 	^ self
       
  2031     ].
       
  2032     (key == #End) ifTrue:[
       
  2033 	index := self size.
       
  2034 	(selectConditionBlock isNil or:[selectConditionBlock value:index]) ifTrue:[
       
  2035 	    self key:key select:[self selection:index] x:x y:y
       
  2036 	].
       
  2037 	^ self
       
  2038     ].
       
  2039     key == #Return ifTrue:[
       
  2040 	selection notNil ifTrue:[
       
  2041 	    doubleClickActionBlock notNil ifTrue:[
       
  2042 		doubleClickActionBlock value:selection
       
  2043 	    ].
       
  2044 	].
       
  2045 	^ self
       
  2046     ].
       
  2047     "
  2423     "
  2048      alphabetic keys: search for next entry
  2424      SelectionInListView new modelInterface 
  2049      starting with keys character. If shift is pressed, search backward
       
  2050     "
  2425     "
  2051     (self size > 0
       
  2052     and:[key isCharacter
       
  2053     and:[key isLetter]]) ifTrue:[
       
  2054 	keyActionStyle isNil ifTrue:[^ self].
       
  2055 	keyActionStyle == #pass ifFalse:[
       
  2056 	    searchPrefix := key asLowercase asString.
       
  2057 
       
  2058 "/            ... isISearch... ifFalse:[
       
  2059 "/                iSearchString := ''
       
  2060 "/            ] ifTrue:[
       
  2061 "/                iSearchString := iSearchString , searchPrefix.
       
  2062 "/                searchPrefix := iSearchString
       
  2063 "/            ].
       
  2064 
       
  2065 	    backSearch := device shiftDown.
       
  2066 	    backSearch ifTrue:[
       
  2067 		selection notNil ifTrue:[
       
  2068 		    selection size > 0 ifTrue:[
       
  2069 			startSearch := selection first - 1
       
  2070 		    ] ifFalse:[
       
  2071 			startSearch := selection - 1
       
  2072 		    ]
       
  2073 		] ifFalse:[
       
  2074 		    startSearch := self size
       
  2075 		].
       
  2076 		startSearch < 1 ifTrue:[
       
  2077 		    startSearch := self size.
       
  2078 		].
       
  2079 	    ] ifFalse:[    
       
  2080 		selection notNil ifTrue:[
       
  2081 		    selection size > 0 ifTrue:[
       
  2082 			startSearch := selection last + 1
       
  2083 		    ] ifFalse:[
       
  2084 			startSearch := selection + 1
       
  2085 		    ]
       
  2086 		] ifFalse:[
       
  2087 		    startSearch := 1
       
  2088 		].
       
  2089 		startSearch > self size ifTrue:[
       
  2090 		    startSearch := 1.
       
  2091 		].
       
  2092 	    ].
       
  2093 	    index := startSearch.
       
  2094 	    [true] whileTrue:[
       
  2095 		(((self at:index) asString) asLowercase startsWith:searchPrefix) ifTrue:[
       
  2096 		    index = selection ifTrue:[^ self].
       
  2097 		    ^ self key:key select:[self selection:index] x:x y:y
       
  2098 		].
       
  2099 		backSearch ifTrue:[
       
  2100 		    index := index - 1.
       
  2101 		    index < 1 ifTrue:[index := self size]
       
  2102 		] ifFalse:[
       
  2103 		    index := index + 1.
       
  2104 		    index > self size ifTrue:[index := 1].
       
  2105 		].
       
  2106 		index == startSearch ifTrue:[
       
  2107 		    ^ self
       
  2108 		]
       
  2109 	    ]
       
  2110 	].
       
  2111     ].
       
  2112     ^ super keyPress:key x:x y:y
       
  2113 
       
  2114 !
       
  2115 
       
  2116 buttonMultiPress:button x:x y:y
       
  2117     ((button == 1) or:[button == #select]) ifTrue:[
       
  2118 	doubleClickActionBlock isNil ifTrue:[
       
  2119 	    self buttonPress:button x:x y:y
       
  2120 	] ifFalse:[
       
  2121 	    doubleClickActionBlock value:selection
       
  2122 	].
       
  2123 	(model notNil and:[doubleClickMsg notNil]) ifTrue:[
       
  2124 	    self sendChangeMessage:doubleClickMsg with:(self argForChangeMessage).
       
  2125 	]
       
  2126     ] ifFalse:[
       
  2127 	super buttonMultiPress:button x:x y:y
       
  2128     ]
       
  2129 !
       
  2130 
       
  2131 buttonShiftPress:button x:x y:y
       
  2132     "add to the selection (if multipleSelectOk); otherwise,
       
  2133      behave like normal select"
       
  2134 
       
  2135     |oldSelection listLineNr|
       
  2136 
       
  2137     ((button == 1) or:[button == #select]) ifTrue:[
       
  2138 	toggleSelect ifTrue:[
       
  2139 	    ^ self buttonPress:button x:x y:y
       
  2140 	].
       
  2141 	enabled ifTrue:[
       
  2142 	    listLineNr := self visibleLineToListLine:(self visibleLineOfY:y).
       
  2143 	    listLineNr notNil ifTrue:[
       
  2144 		(self line:listLineNr hasAttribute:#disabled) ifTrue:[^ self].
       
  2145 
       
  2146 		(selectConditionBlock notNil 
       
  2147 		 and:[(selectConditionBlock value:listLineNr) not]) ifTrue:[^ self].
       
  2148 	    ].
       
  2149 	    oldSelection := selection copy.
       
  2150 	    listLineNr notNil ifTrue: [
       
  2151 		multipleSelectOk ifTrue:[
       
  2152 		    (self isInSelection:listLineNr) ifTrue:[
       
  2153 			self removeFromSelection:listLineNr
       
  2154 		    ] ifFalse:[
       
  2155 			self addToSelection:listLineNr
       
  2156 		    ]
       
  2157 		] ifFalse:[
       
  2158 		    self selectWithoutScroll:listLineNr
       
  2159 		]
       
  2160 	    ].
       
  2161 	    ((ignoreReselect not and:[selection notNil])
       
  2162 	     or:[selection ~= oldSelection]) ifTrue:[
       
  2163 		self selectionChangedFrom:oldSelection.
       
  2164 	    ].
       
  2165 	    clickLine := listLineNr
       
  2166 	]
       
  2167     ] ifFalse:[
       
  2168 	super buttonShiftPress:button x:x y:y
       
  2169     ]
       
  2170 !
       
  2171 
       
  2172 update:something with:aParameter from:changedObject
       
  2173     changedObject == model ifTrue:[
       
  2174 	something == aspectMsg ifTrue:[
       
  2175 	    self getListFromModel.
       
  2176 	    ^ self
       
  2177 	].
       
  2178 	something == initialSelectionMsg ifTrue:[
       
  2179 	    self getSelectionFromModel.
       
  2180 	    ^ self
       
  2181 	].
       
  2182 	something == #empty ifTrue:[
       
  2183 	    self list:nil.
       
  2184 	    ^ self
       
  2185 	].
       
  2186     ].
       
  2187     ^ super update:something with:aParameter from:changedObject
       
  2188 !
       
  2189 
       
  2190 buttonMotion:buttonMask x:x y:y
       
  2191     "mouse-move while button was pressed - handle selection changes"
       
  2192 
       
  2193     |movedVisibleLine movedLine delta oldSelection oldSelCount|
       
  2194 
       
  2195     "is it the select or 1-button ?"
       
  2196     (device buttonMotionMask:buttonMask includesButton:#select) ifFalse:[
       
  2197 	(device buttonMotionMask:buttonMask includesButton:1) ifFalse:[
       
  2198 	    ^ self
       
  2199 	].
       
  2200     ].
       
  2201 
       
  2202     clickLine isNil ifTrue:[^ self].
       
  2203 
       
  2204     "if moved outside of view, start autoscroll"
       
  2205     (y < 0) ifTrue:[
       
  2206 	self compressMotionEvents:false.
       
  2207 	self startAutoScrollUp:y.
       
  2208 	^ self
       
  2209     ].
       
  2210     (y > height) ifTrue:[
       
  2211 	self compressMotionEvents:false.
       
  2212 	self startAutoScrollDown:(y - height).
       
  2213 	^ self
       
  2214     ].
       
  2215 
       
  2216     "move inside - stop autoscroll if any"
       
  2217     self stopAutoScroll.
       
  2218 
       
  2219     movedVisibleLine := self visibleLineOfY:y.
       
  2220     movedLine := self visibleLineToAbsoluteLine:movedVisibleLine.
       
  2221     (movedLine == clickLine) ifTrue:[^ self].
       
  2222 
       
  2223     multipleSelectOk ifTrue:[
       
  2224 	delta := (clickLine < movedLine) ifTrue:[1] ifFalse:[-1].
       
  2225 
       
  2226 	oldSelection := selection.
       
  2227 	oldSelCount := selection size.
       
  2228 
       
  2229 	(clickLine+delta) to:movedLine by:delta do:[:line |
       
  2230 	    (self isInSelection:line) ifTrue:[
       
  2231 		self removeFromSelection:line
       
  2232 	    ] ifFalse:[
       
  2233 		self addToSelection:line
       
  2234 	    ]
       
  2235 	].
       
  2236 	((selection ~= oldSelection)
       
  2237 	 or:[selection size ~~ oldSelCount]) ifTrue:[
       
  2238 	    self selectionChangedFrom:oldSelection.
       
  2239 	]
       
  2240     ] ifFalse:[
       
  2241 "/        self selectWithoutScroll:movedLine
       
  2242     ].
       
  2243 
       
  2244     clickLine := movedLine
       
  2245 ! !
  2426 ! !
       
  2427