rbcurse 1.1.5 → 1.2.0.pre

Sign up to get free protection for your applications and to get access to all the features.
Files changed (123) hide show
  1. data/CHANGELOG +45 -0
  2. data/Makefile +1 -1
  3. data/Manifest.txt +91 -0
  4. data/NOTES +349 -2
  5. data/README.markdown +12 -0
  6. data/VERSION +1 -1
  7. data/examples/abasiclist.rb +25 -0
  8. data/examples/alpmenu.rb +42 -0
  9. data/examples/app.rb +883 -0
  10. data/examples/appcombo.rb +17 -0
  11. data/examples/appdirtree.rb +73 -0
  12. data/examples/appemail.rb +164 -0
  13. data/examples/appemaillb.rb +308 -0
  14. data/examples/appgcompose.rb +303 -0
  15. data/examples/appgmail.rb +951 -0
  16. data/examples/atree.rb +56 -0
  17. data/examples/dirtree.rb +78 -0
  18. data/examples/focusmanager.rb +31 -0
  19. data/examples/imap.rb +48 -0
  20. data/examples/menu1.rb +79 -0
  21. data/examples/multispl.rb +86 -0
  22. data/examples/rfe.rb +3 -4
  23. data/examples/rmail.rb +188 -0
  24. data/examples/s.rb +10 -0
  25. data/examples/scrollbar.rb +104 -0
  26. data/examples/splitp.rb +56 -0
  27. data/examples/table1.rb +30 -0
  28. data/examples/term.rb +48 -0
  29. data/examples/term2.rb +54 -0
  30. data/examples/test1.rb +4 -2
  31. data/examples/test2.rb +9 -9
  32. data/examples/testapp.rb +44 -0
  33. data/examples/testapp2.rb +51 -0
  34. data/examples/testcombo.rb +2 -2
  35. data/examples/testgmail.rb +46 -0
  36. data/examples/testlistbox.rb +0 -1
  37. data/examples/testmultispl.rb +199 -0
  38. data/examples/testree.rb +127 -0
  39. data/examples/testscroller.rb +0 -1
  40. data/examples/testscrolllb.rb +1 -1
  41. data/examples/testscrollp.rb +2 -1
  42. data/examples/testscrollta.rb +1 -1
  43. data/examples/testscrolltable.rb +1 -2
  44. data/examples/testsplit.rb +1 -1
  45. data/examples/testsplit2.rb +1 -1
  46. data/examples/testsplit3.rb +1 -1
  47. data/examples/testsplit3_1.rb +1 -1
  48. data/examples/testsplit3a.rb +1 -1
  49. data/examples/testsplit3b.rb +1 -1
  50. data/examples/testsplitta.rb +1 -1
  51. data/examples/testsplittv.rb +1 -1
  52. data/examples/testsplittvv.rb +1 -1
  53. data/examples/testtodo.rb +491 -488
  54. data/examples/testvimsplit.rb +111 -0
  55. data/examples/todo.db +0 -0
  56. data/examples/todocsv.csv +28 -0
  57. data/examples/viewtodo.rb +408 -403
  58. data/lib/rbcurse/action.rb +1 -0
  59. data/lib/rbcurse/app.rb +1294 -0
  60. data/lib/rbcurse/applicationheader.rb +7 -2
  61. data/lib/rbcurse/checkboxcellrenderer.rb +0 -12
  62. data/lib/rbcurse/colormap.rb +34 -8
  63. data/lib/rbcurse/comboboxcellrenderer.rb +0 -11
  64. data/lib/rbcurse/defaultlistselectionmodel.rb +23 -7
  65. data/lib/rbcurse/extras/bottomline.rb +1681 -0
  66. data/lib/rbcurse/extras/directorylist.rb +445 -0
  67. data/lib/rbcurse/extras/directorytree.rb +69 -0
  68. data/lib/rbcurse/extras/divider.rb +310 -0
  69. data/lib/rbcurse/extras/focusmanager.rb +31 -0
  70. data/lib/rbcurse/extras/listselectable.rb +222 -0
  71. data/lib/rbcurse/extras/masterdetail.rb +164 -0
  72. data/lib/rbcurse/extras/menutree.rb +63 -0
  73. data/lib/rbcurse/extras/rlink.rb +27 -0
  74. data/lib/rbcurse/extras/rmenulink.rb +21 -0
  75. data/lib/rbcurse/extras/scrollbar.rb +134 -0
  76. data/lib/rbcurse/extras/stdscrwindow.rb +247 -0
  77. data/lib/rbcurse/extras/tabular.rb +258 -0
  78. data/lib/rbcurse/extras/tabularwidget.rb +1070 -0
  79. data/lib/rbcurse/extras/viewer.rb +106 -0
  80. data/lib/rbcurse/io.rb +137 -80
  81. data/lib/rbcurse/keylabelprinter.rb +4 -0
  82. data/lib/rbcurse/listcellrenderer.rb +91 -59
  83. data/lib/rbcurse/listscrollable.rb +93 -95
  84. data/lib/rbcurse/listselectable.rb +60 -7
  85. data/lib/rbcurse/ractionevent.rb +67 -0
  86. data/lib/rbcurse/rbasiclistbox.rb +688 -0
  87. data/lib/rbcurse/rcombo.rb +5 -5
  88. data/lib/rbcurse/rcommandwindow.rb +555 -0
  89. data/lib/rbcurse/rinputdataevent.rb +12 -0
  90. data/lib/rbcurse/rlistbox.rb +305 -124
  91. data/lib/rbcurse/rmenu.rb +99 -46
  92. data/lib/rbcurse/rmessagebox.rb +13 -6
  93. data/lib/rbcurse/rmulticontainer.rb +54 -93
  94. data/lib/rbcurse/rmultisplit.rb +731 -0
  95. data/lib/rbcurse/rmultitextview.rb +3 -2
  96. data/lib/rbcurse/rpopupmenu.rb +0 -1
  97. data/lib/rbcurse/rprogress.rb +117 -0
  98. data/lib/rbcurse/rscrollpane.rb +2 -1
  99. data/lib/rbcurse/rsplitpane.rb +94 -20
  100. data/lib/rbcurse/rsplitpane2.rb +1009 -0
  101. data/lib/rbcurse/rtabbedpane.rb +3 -2
  102. data/lib/rbcurse/rtabbedwindow.rb +0 -1
  103. data/lib/rbcurse/rtable.rb +92 -64
  104. data/lib/rbcurse/rtextarea.rb +91 -57
  105. data/lib/rbcurse/rtextview.rb +223 -70
  106. data/lib/rbcurse/rtree.rb +723 -0
  107. data/lib/rbcurse/rviewport.rb +2 -1
  108. data/lib/rbcurse/rvimsplit.rb +768 -0
  109. data/lib/rbcurse/rwidget.rb +524 -325
  110. data/lib/rbcurse/table/tablecellrenderer.rb +1 -1
  111. data/lib/rbcurse/table/tabledatecellrenderer.rb +0 -1
  112. data/lib/rbcurse/tree/treecellrenderer.rb +137 -0
  113. data/lib/rbcurse/tree/treemodel.rb +428 -0
  114. data/lib/rbcurse/vieditable.rb +14 -13
  115. data/lib/ver/ncurses.rb +6 -0
  116. data/lib/ver/window.rb +67 -32
  117. metadata +99 -23
  118. data/bin/rbcurse +0 -0
  119. data/examples/rvimsplit.rb +0 -376
  120. data/examples/todo.rb +0 -1
  121. data/lib/rbcurse/rform.rb +0 -845
  122. data/lib/rbcurse/selectable.rb +0 -94
  123. data/rbcurse.gemspec +0 -188
@@ -11,6 +11,8 @@ module ListScrollable
11
11
  attr_reader :search_found_ix, :find_offset, :find_offset1
12
12
  attr_accessor :show_caret # 2010-01-23 23:06 our own fake insertion point
13
13
  def previous_row num=(($multiplier.nil? or $multiplier == 0) ? 1 : $multiplier)
14
+ #return :UNHANDLED if @current_index == 0 # EVIL
15
+ return false if @current_index == 0
14
16
  @oldrow = @current_index
15
17
  # NOTE that putting a multiplier inside, prevents an event from being triggered for each row's
16
18
  # on leave and on enter
@@ -22,8 +24,13 @@ module ListScrollable
22
24
  end
23
25
  alias :up :previous_row
24
26
  def next_row num=(($multiplier.nil? or $multiplier == 0) ? 1 : $multiplier)
25
- @oldrow = @current_index
26
27
  rc = row_count
28
+ # returning unhandled was clever .. when user hits down arrow on last row the focus goes to
29
+ # next field. however, in long lists when user scrolls the sudden jumping to next is very annoying.
30
+ # In combos, if focus was on last row, the combo closed which is not accceptable.
31
+ #return :UNHANDLED if @current_index == rc-1 # EVIL !!!
32
+ return false if @current_index == rc-1
33
+ @oldrow = @current_index
27
34
  @current_index += 1*num if @current_index < rc
28
35
  bounds_check
29
36
  $multiplier = 0
@@ -72,10 +79,10 @@ module ListScrollable
72
79
  def bounds_check
73
80
  h = scrollatrow()
74
81
  rc = row_count
75
- #$log.debug " PRE CURR:#{@current_index}, TR: #{@toprow} RC: #{rc} H:#{h}"
82
+
76
83
  @current_index = 0 if @current_index < 0 # not lt 0
77
- @current_index = rc-1 if @current_index >= rc and rc>0 # not gt rowcount
78
- @toprow = rc-h-1 if rc > h and @toprow > rc - h - 1 # toprow shows full page if possible
84
+ @current_index = rc-1 if @current_index >= rc && rc>0 # not gt rowcount
85
+ @toprow = rc-h-1 if rc > h && @toprow > rc - h - 1 # toprow shows full page if possible
79
86
  # curr has gone below table, move toprow forward
80
87
  if @current_index - @toprow > h
81
88
  @toprow = @current_index - h
@@ -83,9 +90,9 @@ module ListScrollable
83
90
  # curr has gone above table, move toprow up
84
91
  @toprow = @current_index
85
92
  end
86
- #$log.debug " POST CURR:#{@current_index}, TR: #{@toprow} RC: #{rc} H:#{h}"
93
+
87
94
  if @oldrow != @current_index
88
- #$log.debug "going to call on leave and on enter"
95
+
89
96
  on_leave_row @oldrow if respond_to? :on_leave_row # to be defined by widget that has included this
90
97
  on_enter_row @current_index if respond_to? :on_enter_row # to be defined by widget that has included this
91
98
  end
@@ -98,23 +105,23 @@ module ListScrollable
98
105
  r,c = rowcol
99
106
  @rows_panned ||= 0
100
107
 
101
- #win_row=@form.window.top
102
- win_row=@win_top # 2010-02-11 15:12 RFED16
103
108
  win_row = 0 # 2010-02-07 21:44 now ext offset added by widget
104
- #win_row = 0 # new approach, we have it
105
- #win_col=@form.window.left
106
- # added 1 ?? in copywin too 2010-02-11 18:51 RFED16 this results in extra in normal situations.
109
+
110
+ # when the toprow is set externally then cursor can be mispositioned since
111
+ # bounds_check has not been called
112
+ if @current_index < @toprow
113
+ # cursor is outside table
114
+ @current_index = @toprow # ??? only if toprow 2010-10-19 12:56
115
+ end
116
+
107
117
  row = win_row + r + (@current_index-@toprow) + @rows_panned
108
- $log.debug " #{@name} LIST set_form_row #{row} = ci #{@current_index} + r #{r} + winrow: #{win_row} - tr:#{@toprow} #{@toprow} + rowsp #{@rows_panned} "
109
- $log.debug " - LIST set_form_row row_offset: #{@row_offset} + r #{r} + ci - topr + rowsp: #{@rows_panned}. c= #{c} "
118
+ #$log.debug " #{@name} set_form_row #{row} = ci #{@current_index} + r #{r} + winrow: #{win_row} - tr:#{@toprow} #{@toprow} + rowsp #{@rows_panned} "
119
+ # row should not be < r or greater than r+height TODO FIXME
110
120
 
111
- ## 2009-12-28 23:05 TRYING OUT but i really can't do this everywhere. BUFFERED
112
- ## this needs to percolate up a heirarchy.
113
- ## 2010-01-05 21:09 changed c to nil, since c is not cursor col pos but where printing starts, i think
114
- #@form.setrowcol row, nil
115
- #setformrowcol row, nil
121
+
122
+
116
123
  setrowcol row, nil
117
- show_caret_func
124
+ #show_caret_func
118
125
  end
119
126
  ## In many situations like placing a textarea or textview inside a splitpane
120
127
  ##+ or scrollpane there have been issues getting the cursor at the right point,
@@ -186,54 +193,17 @@ module ListScrollable
186
193
  end
187
194
  #alias :current_index :focussed_index
188
195
  alias :selected_index :focussed_index
189
- def OLDscrollable_handle_key ch
190
- begin
191
- ###pre_key # 2009-01-07 13:23
192
- case ch
193
- when ?\C-n.getbyte(0)
194
- scroll_forward
195
- when 32
196
- scroll_forward
197
- when ?\C-p.getbyte(0)
198
- scroll_backward
199
- when ?0.getbyte(0)
200
- #goto_start
201
- goto_top
202
- when ?9.getbyte(0)
203
- #goto_end
204
- goto_bottom
205
- when KEY_UP
206
- #select_prev_row
207
- #up
208
- #$log.debug " GOT KEY UP NEW SCROLL"
209
- previous_row
210
- when KEY_LEFT
211
- when KEY_RIGHT
212
- when KEY_DOWN
213
- #down
214
- #$log.debug " GOT KEY DOWN NEW SCROLL"
215
- next_row
216
- when KEY_ENTER, 10, 13
217
- if respond_to? :fire
218
- fire
219
- end
220
- when ?A.getbyte(0)..?Z.getbyte(0), ?a.getbyte(0)..?z.getbyte(0)
221
- ret = set_selection_for_char ch.chr
222
- else
223
- return :UNHANDLED #if ret == -1
224
- end
225
- ensure
226
- #post_key
227
- end
228
- end # handle_k listb
229
- ## 2008-12-18 18:03
196
+
230
197
  # finds the next match for the char pressed
231
198
  # returning the index
199
+ # If we are only checking first char, then why chomp ?
200
+ # Please note that this is used now by tree, and list can have non-strings, so use to_s
232
201
  def next_match char
233
202
  data = get_content
234
203
  row = focussed_index + 1
235
204
  row.upto(data.length-1) do |ix|
236
- val = data[ix].chomp rescue return # 2010-01-05 15:28 crashed on trueclass
205
+ #val = data[ix].chomp rescue return # 2010-01-05 15:28 crashed on trueclass
206
+ val = data[ix].to_s rescue return # 2010-01-05 15:28 crashed on trueclass
237
207
  #if val[0,1] == char #and val != currval
238
208
  if val[0,1].casecmp(char) == 0 #AND VAL != CURRval
239
209
  return ix
@@ -241,7 +211,8 @@ module ListScrollable
241
211
  end
242
212
  row = focussed_index - 1
243
213
  0.upto(row) do |ix|
244
- val = data[ix].chomp
214
+ #val = data[ix].chomp
215
+ val = data[ix].to_s
245
216
  #if val[0,1] == char #and val != currval
246
217
  if val[0,1].casecmp(char) == 0 #and val != currval
247
218
  return ix
@@ -253,8 +224,10 @@ module ListScrollable
253
224
  # sets the selection to the next row starting with char
254
225
  def set_selection_for_char char
255
226
  @oldrow = @current_index
227
+ @last_regex = "^#{char}"
256
228
  ix = next_match char
257
229
  @current_index = ix if ix && ix != -1
230
+ @search_found_ix = @current_index
258
231
  bounds_check
259
232
  return ix
260
233
  end
@@ -269,25 +242,6 @@ module ListScrollable
269
242
  bounds_check if @oldrow != @current_index
270
243
  end
271
244
  ##
272
- # 2008-12-18 18:05
273
- # set focus on given index
274
- def OLDset_focus_on arow
275
- return if arow > row_count()-1 or arow < 0
276
- @oldrow = @current_index
277
- total = row_count()
278
- @current_index = arow
279
- sar = scrollatrow + 1
280
- @toprow = (@current_index / sar) * sar
281
-
282
- #$log.debug "1 set_focus #{total}, sar #{sar}, toprow #{@toprow}, current_index #{@current_index}"
283
- if total - @toprow < sar
284
- @toprow = (total - sar)
285
- end
286
- #$log.debug "2 set_focus #{total}, sar #{sar}, toprow #{@toprow}, current_index #{@current_index}"
287
- set_form_row # 2009-01-17 12:44
288
- @repaint_required = true
289
- #bounds_check
290
- end
291
245
  def install_keys
292
246
  =begin
293
247
  @KEY_ASK_FIND_FORWARD ||= ?\M-f.getbyte(0)
@@ -328,7 +282,8 @@ module ListScrollable
328
282
  # find forwards
329
283
  # Using this to start a search or continue search
330
284
  def _find_next regex=@last_regex, start = @search_found_ix
331
- raise "No previous search" if regex.nil?
285
+ #raise "No previous search" if regex.nil?
286
+ warn "No previous search" and return if regex.nil?
332
287
  #$log.debug " _find_next #{@search_found_ix} : #{@current_index}"
333
288
  fend = @list.size-1
334
289
  if start != fend
@@ -337,7 +292,7 @@ module ListScrollable
337
292
  @search_start_ix = start
338
293
  regex = Regexp.new(regex, Regexp::IGNORECASE) if @search_case
339
294
  start.upto(fend) do |ix|
340
- row = @list[ix]
295
+ row = @list[ix].to_s
341
296
  m=row.match(regex)
342
297
  if !m.nil?
343
298
  @find_offset = m.offset(0)[0]
@@ -351,7 +306,7 @@ module ListScrollable
351
306
  start = 0
352
307
  if @search_wrap
353
308
  start.upto(fend) do |ix|
354
- row = @list[ix]
309
+ row = @list[ix].to_s
355
310
  m=row.match(regex)
356
311
  if !m.nil?
357
312
  @find_offset = m.offset(0)[0]
@@ -364,6 +319,10 @@ module ListScrollable
364
319
  return nil
365
320
  end
366
321
  def find_next
322
+ unless @last_regex
323
+ alert("No previous search. Search first.")
324
+ return
325
+ end
367
326
  ix = _find_next
368
327
  regex = @last_regex
369
328
  if ix.nil?
@@ -375,6 +334,10 @@ module ListScrollable
375
334
  end
376
335
  end
377
336
  def find_prev
337
+ unless @last_regex
338
+ alert("No previous search. Search first.")
339
+ return
340
+ end
378
341
  ix = _find_prev
379
342
  regex = @last_regex
380
343
  if ix.nil?
@@ -389,7 +352,8 @@ module ListScrollable
389
352
  # find backwards
390
353
  # Using this to start a search or continue search
391
354
  def _find_prev regex=@last_regex, start = @search_found_ix
392
- raise "No previous search" if regex.nil?
355
+ #raise "No previous search" if regex.nil?
356
+ warn "No previous search" and return if regex.nil?
393
357
  #$log.debug " _find_prev #{@search_found_ix} : #{@current_index}"
394
358
  if start != 0
395
359
  start -= 1 unless start == 0
@@ -397,7 +361,7 @@ module ListScrollable
397
361
  @search_start_ix = start
398
362
  regex = Regexp.new(regex, Regexp::IGNORECASE) if @search_case
399
363
  start.downto(0) do |ix|
400
- row = @list[ix]
364
+ row = @list[ix].to_s
401
365
  m=row.match(regex)
402
366
  if !m.nil?
403
367
  @find_offset = m.offset(0)[0]
@@ -411,7 +375,7 @@ module ListScrollable
411
375
  start = @list.size-1
412
376
  if @search_wrap
413
377
  start.downto(fend) do |ix|
414
- row = @list[ix]
378
+ row = @list[ix].to_s
415
379
  m=row.match(regex)
416
380
  if !m.nil?
417
381
  @find_offset = m.offset(0)[0]
@@ -425,18 +389,25 @@ module ListScrollable
425
389
  end
426
390
  ##
427
391
  # goes to start of next word (or n words) - vi's w
392
+ # NOTE: will not work if the list has different data from what is displayed
393
+ # Nothing i can do about it.
394
+ # Also does not work as expected if consecutive spaces FIXME
428
395
  #
429
396
  def forward_word
430
- $multiplier = 1 if !$multiplier or $multiplier == 0
397
+ $multiplier = 1 if !$multiplier || $multiplier == 0
431
398
  line = @current_index
432
- buff = @list[line]
399
+ buff = @list[line].to_s
433
400
  pos = @curpos
434
401
  $multiplier.times {
435
402
  found = buff.index(/[[:punct:][:space:]]/, pos)
436
403
  if !found
437
404
  # if not found, we've lost a counter
438
- line += 1 # unless eof
439
- buff = @list[line]
405
+ if line+1 < @list.length
406
+ line += 1
407
+ else
408
+ return
409
+ end
410
+ buff = @list[line].to_s
440
411
  pos = 0
441
412
  else
442
413
  pos = found + 1
@@ -445,7 +416,7 @@ module ListScrollable
445
416
  }
446
417
  @current_index = line
447
418
  @curpos = pos
448
- @buffer = @list[@current_index]
419
+ @buffer = @list[@current_index].to_s
449
420
  set_form_row
450
421
  set_form_col pos
451
422
  @repaint_required = true
@@ -465,7 +436,7 @@ module ListScrollable
465
436
  $log.debug " forward_char char:#{char}:"
466
437
  $multiplier = 1 if !$multiplier or $multiplier == 0
467
438
  line = @current_index
468
- buff = @list[line]
439
+ buff = @list[line].to_s
469
440
  pos = @curpos
470
441
  $multiplier.times {
471
442
  found = false
@@ -473,7 +444,7 @@ module ListScrollable
473
444
  found = buff.index(char, pos)
474
445
  if !found
475
446
  line += 1 # unless eof
476
- buff = @list[line]
447
+ buff = @list[line].to_s
477
448
  pos = 0
478
449
  else
479
450
  pos = found + 1
@@ -484,11 +455,38 @@ module ListScrollable
484
455
  }
485
456
  @current_index = line
486
457
  @curpos = pos
487
- @buffer = @list[@current_index]
458
+ @buffer = @list[@current_index].to_s
488
459
  set_form_row
489
460
  set_form_col pos
490
461
  @repaint_required = true
491
462
  end
463
+ # takes a block, this way anyone extending this class can just pass a block to do his job
464
+ # This modifies the string
465
+ def sanitize content #:nodoc:
466
+ if content.is_a? String
467
+ content.chomp!
468
+ content.gsub!(/\t/, ' ') # don't display tab
469
+ content.gsub!(/[^[:print:]]/, '') # don't display non print characters
470
+ else
471
+ content
472
+ end
473
+ end
474
+ # returns only the visible portion of string taking into account display length
475
+ # and horizontal scrolling. MODIFIES STRING
476
+ def truncate content #:nodoc:
477
+ maxlen = @maxlen || @width-2
478
+ if !content.nil?
479
+ if content.length > maxlen # only show maxlen
480
+ @longest_line = content.length if content.length > @longest_line
481
+ #content = content[@pcol..@pcol+maxlen-1]
482
+ content.replace content[@pcol..@pcol+maxlen-1]
483
+ else
484
+ # can this be avoided if pcol is 0 XXX
485
+ content.replace content[@pcol..-1] if @pcol > 0
486
+ end
487
+ end
488
+ content
489
+ end
492
490
 
493
491
 
494
492
  end
@@ -4,54 +4,92 @@ module RubyCurses
4
4
  module ListSelectable
5
5
 
6
6
  ## modified on 2009-02-13 23:41 to return model if no param passed
7
+ # sets or returns a list selection model
8
+ # Also listbox listens to it for selections, so it can tell those
9
+ # who are interested 2010-09-21 16:02
7
10
  def list_selection_model(*lsm)
8
11
  if lsm.empty?
9
12
  @list_selection_model
10
13
  else
11
14
  @list_selection_model = lsm[0]
15
+ # the listbox is listening to selection events on the
16
+ # selection model and will inform any listeners of the same.
17
+ @list_selection_model.bind :LIST_SELECTION_EVENT do |ev|
18
+ fire_handler :LIST_SELECTION_EVENT, ev
19
+ end
12
20
  end
13
21
  #@list_selection_model.selection_mode = @selection_mode || :MULTIPLE
14
22
  end
15
- def create_default_list_selection_model
16
- list_selection_model DefaultListSelectionModel.new
17
- end
18
- def is_row_selected row
23
+ def is_selected? row
19
24
  @list_selection_model.is_selected_index row
20
25
  end
26
+ # this is the old name, should be deprecated
27
+ alias :is_row_selected :is_selected?
21
28
 
22
29
  def add_row_selection_interval ix0, ix1
23
30
  $log.debug " def add_row_selection_interval #{ix0}, ix1"
24
31
  # if row_selection_allowed
25
32
  @list_selection_model.add_selection_interval ix0, ix1
33
+ @repaint_required = true
26
34
  end
27
35
  def remove_row_selection_interval ix0, ix1
28
36
  @list_selection_model.remove_selection_interval ix0, ix1
29
37
  end
30
38
  def toggle_row_selection row=@current_index
31
- if is_row_selected row
32
- $log.debug " deleting row #{row}"
39
+ if is_selected? row
40
+ #$log.debug " deleting row #{row}"
33
41
  remove_row_selection_interval(row, row)
34
42
  else
35
- $log.debug " adding row #{row}"
43
+ #$log.debug " adding row #{row}"
36
44
  add_row_selection_interval(row, row)
37
45
  end
46
+ @repaint_required = true
38
47
  end
39
48
 
40
49
  def clear_selection
41
50
  @list_selection_model.clear_selection
51
+ @repaint_required = true
42
52
  end
53
+ # why is this commented off XXX could it override listscrollable
43
54
  def selected_item
44
55
  # @list[@current_index]
45
56
  end
57
+ # returns selected indices
58
+ # TODO : if array passed, set those as selected indices
46
59
  def selected_rows
47
60
  @list_selection_model.get_selected_rows
48
61
  end
49
62
  def selected_row_count
50
63
  selected_rows.size
51
64
  end
65
+ # returns index of first selected row (lowest index)
66
+ # TODO: if param passed set that as selected_index
52
67
  def selected_row
53
68
  @list_selection_model.get_min_selection_index
54
69
  end
70
+ alias :selected_index :selected_row
71
+
72
+ # returns value of first selected row (lowest index)
73
+ def selected_value
74
+ #@list[@current_index].to_s # old behavior since curr row was in reverse
75
+ return nil if selected_row().nil?
76
+ @list[selected_row()].to_s
77
+ end
78
+ # returns an array of selected values
79
+ # or yields values to given block
80
+ def selected_values &block
81
+ ar = []
82
+ selected_rows().each do |i|
83
+ val = @list[i]
84
+ if block_given?
85
+ yield val
86
+ else
87
+ ar << val
88
+ end
89
+ end
90
+ return ar unless block_given?
91
+ end
92
+
55
93
  def do_next_selection
56
94
  return if selected_rows().length == 0
57
95
  row = selected_rows().sort.find { |i| i > @current_index }
@@ -66,10 +104,25 @@ module RubyCurses
66
104
  @current_index = row
67
105
  @repaint_required = true # fire list_select XXX
68
106
  end
107
+ # NOTE: I HAD removed this and put in listbox, but its required by rtable also
108
+ # create a default list selection model and set it
109
+ # NOTE: I am now checking if one is not already created, since
110
+ # a second creation would wipe out any listeners on it.
111
+ # @see ListSelectable
112
+ # @see DefaultListSelectionModel
113
+ def create_default_list_selection_model
114
+ if @list_selection_model.nil?
115
+ list_selection_model DefaultListSelectionModel.new(self)
116
+ end
117
+ end
69
118
  alias :selected_index :selected_row
70
119
  attr_accessor :row_selection_allowed
71
120
  attr_accessor :column_selection_allowed
72
121
  end
122
+ # class containing information relating to selections on a list
123
+ # 2010-09-21 19:46 NOTE: Earlier source contained the model object, now it returns the parent
124
+ # You may do source.list_data_model() to get the model
125
+ # Typical operations on source would get selected_value(s), or selected_index
73
126
  class ListSelectionEvent
74
127
  attr_accessor :firstrow, :lastrow, :source, :type
75
128
  def initialize firstrow, lastrow, source, type