rkumar-rbcurse 0.1.1 → 0.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -3,8 +3,13 @@
3
3
  module RubyCurses
4
4
  module ListSelectable
5
5
 
6
- def list_selection_model lsm
7
- @list_selection_model = lsm
6
+ ## modified on 2009-02-13 23:41 to return model if no param passed
7
+ def list_selection_model(*lsm)
8
+ if lsm.empty?
9
+ @list_selection_model
10
+ else
11
+ @list_selection_model = lsm[0]
12
+ end
8
13
  #@list_selection_model.selection_mode = @selection_mode || :MULTIPLE
9
14
  end
10
15
  def create_default_list_selection_model
@@ -15,6 +20,7 @@ module RubyCurses
15
20
  end
16
21
 
17
22
  def add_row_selection_interval ix0, ix1
23
+ $log.debug " def add_row_selection_interval #{ix0}, ix1"
18
24
  # if row_selection_allowed
19
25
  @list_selection_model.add_selection_interval ix0, ix1
20
26
  end
@@ -64,4 +70,19 @@ module RubyCurses
64
70
  attr_accessor :row_selection_allowed
65
71
  attr_accessor :column_selection_allowed
66
72
  end
73
+ class ListSelectionEvent
74
+ attr_accessor :firstrow, :lastrow, :source, :type
75
+ def initialize firstrow, lastrow, source, type
76
+ @firstrow = firstrow
77
+ @lastrow = lastrow
78
+ @source = source
79
+ @type = type
80
+ end
81
+ def to_s
82
+ "#{@type.to_s}, firstrow: #{@firstrow}, lastrow: #{@lastrow}, source: #{@source}"
83
+ end
84
+ def inspect
85
+ to_s
86
+ end
87
+ end
67
88
  end
@@ -44,6 +44,7 @@ module RubyCurses
44
44
  include Enumerable
45
45
  include RubyCurses::EventHandler
46
46
  attr_accessor :selected_index
47
+ attr_reader :last_regex # should i really keep here as public or maintain in listbox
47
48
 
48
49
  def initialize anarray
49
50
  @list = anarray.dup
@@ -64,6 +65,7 @@ module RubyCurses
64
65
  @list.index(obj)
65
66
  end
66
67
  def length ; @list.length; end
68
+ alias :size :length
67
69
 
68
70
  def insert off0, *data
69
71
  @list.insert off0, *data
@@ -112,7 +114,7 @@ module RubyCurses
112
114
  @list.dup
113
115
  end
114
116
  def on_enter_row object
115
- $log.debug " XXX on_enter_row of list_data"
117
+ #$log.debug " XXX on_enter_row of list_data"
116
118
  fire_handler :ENTER_ROW, object
117
119
  end
118
120
  # ##
@@ -143,10 +145,10 @@ module RubyCurses
143
145
  return find_match @last_regex, start, @search_end_ix
144
146
  end
145
147
  ##
146
- # find backwards
148
+ # find backwards, list_data_model
147
149
  # Using this to start a search or continue search
148
150
  def find_prev regex=@last_regex, start = @search_found_ix
149
- raise "No previous search" if @last_regex.nil?
151
+ raise "No previous search" if regex.nil? # @last_regex.nil?
150
152
  $log.debug " find_prev #{@search_found_ix} : #{@current_index}"
151
153
  start -= 1 unless start == 0
152
154
  @last_regex = regex
@@ -427,6 +429,7 @@ module RubyCurses
427
429
  select_default_values
428
430
  # when the combo box has a certain row in focus, the popup should have the same row in focus
429
431
 
432
+ install_keys
430
433
  init_vars
431
434
  install_list_keys
432
435
 
@@ -531,7 +534,7 @@ module RubyCurses
531
534
  h = scrollatrow()
532
535
  rc = row_count
533
536
  $log.debug " listbxo got ch #{ch}"
534
- $log.debug " when kps #{@KEY_PREV_SELECTION} "
537
+ #$log.debug " when kps #{@KEY_PREV_SELECTION} "
535
538
  case ch
536
539
  when KEY_UP # show previous value
537
540
  previous_row
@@ -565,14 +568,21 @@ module RubyCurses
565
568
  @repaint_required = true
566
569
  when 27, ?\C-c:
567
570
  editing_canceled @current_index if @cell_editing_allowed
571
+ cancel_block # block
568
572
  when @KEY_ASK_FIND_FORWARD
569
- ask_search_forward
573
+ # ask_search_forward
570
574
  when @KEY_ASK_FIND_BACKWARD
571
- ask_search_backward
575
+ # ask_search_backward
572
576
  when @KEY_FIND_NEXT
573
- find_next
577
+ # find_next
574
578
  when @KEY_FIND_PREV
575
- find_prev
579
+ # find_prev
580
+ when @KEY_ASK_FIND
581
+ ask_search
582
+ when @KEY_FIND_MORE
583
+ find_more
584
+ when @KEY_BLOCK_SELECTOR
585
+ mark_block #selection
576
586
  else
577
587
  # this has to be fixed, if compo does not handle key it has to continue into next part FIXME
578
588
  ret = :UNHANDLED # changed on 2009-01-27 13:14 not going into unhandled, tab not released
@@ -606,8 +616,10 @@ module RubyCurses
606
616
  set_focus_on(ix)
607
617
  end
608
618
  end
619
+ # gets string to search and calls data models find prev
609
620
  def ask_search_backward
610
621
  regex = get_string("Enter regex to search (backward)")
622
+ @last_regex = regex
611
623
  ix = @list.find_prev regex, @current_index
612
624
  if ix.nil?
613
625
  alert("No matching data for: #{regex}")
@@ -615,7 +627,8 @@ module RubyCurses
615
627
  set_focus_on(ix)
616
628
  end
617
629
  end
618
- def find_prev
630
+ ## listbox find_prev
631
+ def OLDfind_prev
619
632
  ix = @list.find_prev
620
633
  regex = @last_regex
621
634
  if ix.nil?
@@ -627,7 +640,7 @@ module RubyCurses
627
640
  end
628
641
  end
629
642
  # table find_next
630
- def find_next
643
+ def OLDfind_next
631
644
  ix = @list.find_next
632
645
  regex = @last_regex
633
646
  if ix.nil?
@@ -639,12 +652,12 @@ module RubyCurses
639
652
  def on_enter
640
653
  on_enter_row @current_index
641
654
  set_form_row # added 2009-01-11 23:41
642
- $log.debug " ONE ENTER LIST #{@current_index}, #{@form.row}"
643
- @repaint_required
655
+ #$log.debug " ONE ENTER LIST #{@current_index}, #{@form.row}"
656
+ @repaint_required = true
644
657
  fire_handler :ENTER, self
645
658
  end
646
659
  def on_enter_row arow
647
- $log.debug " Listbox #{self} ENTER_ROW with curr #{@current_index}. row: #{arow} H: #{@handler.keys}"
660
+ #$log.debug " Listbox #{self} ENTER_ROW with curr #{@current_index}. row: #{arow} H: #{@handler.keys}"
648
661
  #fire_handler :ENTER_ROW, arow
649
662
  fire_handler :ENTER_ROW, self
650
663
  @list.on_enter_row self
@@ -668,7 +681,8 @@ module RubyCurses
668
681
  col = c+@left_margin # @form.col
669
682
  # unfortunately 2009-01-11 19:47 combo boxes editable allows changing value
670
683
  editor.prepare_editor self, row, col, value
671
- set_form_col @left_margin
684
+ editor.component.curpos = 0 # reset it after search, if user scrols down
685
+ set_form_col 0 #@left_margin
672
686
 
673
687
  # set original value so we can cancel
674
688
  # set row and col,
@@ -676,7 +690,7 @@ module RubyCurses
676
690
  end
677
691
  def on_leave_row arow
678
692
  #$log.debug " Listbox #{self} leave with (cr: #{@current_index}) #{arow}: list[row]:#{@list[arow]}"
679
- $log.debug " Listbox #{self} leave with (cr: #{@current_index}) #{arow}: "
693
+ #$log.debug " Listbox #{self} leave with (cr: #{@current_index}) #{arow}: "
680
694
  #fire_handler :LEAVE_ROW, arow
681
695
  fire_handler :LEAVE_ROW, self
682
696
  editing_completed arow
@@ -797,7 +811,47 @@ module RubyCurses
797
811
  end
798
812
  @repaint_required = true
799
813
  end
814
+ def set_form_col col=0
815
+ super col+@left_margin
816
+ end
817
+ # experimental selection of multiple rows via block
818
+ # specify a block start and then a block end
819
+ # usage: bind mark_selection to a key. It works as a toggle.
820
+ # C-c will cancel any selection that has begun.
821
+ # added on 2009-02-19 22:37
822
+ def mark_block #selection
823
+ if @inside_block
824
+ @inside_block = false
825
+ end_block #selection
826
+ else
827
+ @inside_block = true
828
+ start_block #selection
829
+ end
830
+ end
831
+ # added on 2009-02-19 22:37
832
+ def cancel_block
833
+ @first_index = @last_index = nil
834
+ @inside_block = false
835
+ end
836
+ # sets marker for start of block
837
+ # added on 2009-02-19 22:37
838
+ def start_block #selection
839
+ @first_index = @current_index
840
+ @last_index = nil
841
+ end
842
+ # sets marker for end of block
843
+ # added on 2009-02-19 22:37
844
+ def end_block #selection
845
+ @last_index = current_index
846
+ lower = [@first_index, @last_index].min
847
+ higher = [@first_index, @last_index].max
848
+ #lower.upto(higher) do |i| @list.toggle_row_selection i; end
849
+ add_row_selection_interval(lower, higher)
850
+ @repaint_required = true
851
+ end
852
+
800
853
 
854
+ # ADD HERE
801
855
  end # class listb
802
856
 
803
857
 
@@ -111,8 +111,14 @@ module RubyCurses
111
111
  make_buttons ["&OK"]
112
112
  when "ok_cancel" #, "input", "list", "field_list"
113
113
  make_buttons %w[&OK &Cancel]
114
+ # experience 2009-02-22 12:52 trapping y and n - hopefully wont cause an edit problem
115
+ @form.bind_key(?o){ press(?\M-o) }
116
+ @form.bind_key(?c){ press(?\M-c) }
114
117
  when "yes_no"
115
118
  make_buttons %w[&Yes &No]
119
+ # experience 2009-02-22 12:52 trapping y and n - hopefully wont cause an edit problem
120
+ @form.bind_key(?y){ press(?\M-y) }
121
+ @form.bind_key(?n){ press(?\M-n) }
116
122
  when "yes_no_cancel"
117
123
  make_buttons ["&Yes", "&No", "&Cancel"]
118
124
  when "custom"
@@ -170,7 +176,6 @@ module RubyCurses
170
176
  return @selected_index
171
177
  end
172
178
  def press ch
173
- #$log.debug "message box handle_keys : #{ch}" if ch != -1
174
179
  case ch
175
180
  when -1
176
181
  return
@@ -183,12 +188,14 @@ module RubyCurses
183
188
  if field.respond_to? :fire
184
189
  field.fire
185
190
  end
186
- $log.debug "popup ENTER : #{@selected_index} "
187
- $log.debug "popup ENTER : #{field.name}" if !field.nil?
191
+ #$log.debug "popup ENTER : #{@selected_index} "
192
+ #$log.debug "popup ENTER : #{field.name}" if !field.nil?
188
193
  @stop = true
189
194
  return
190
195
  when 9
191
196
  @form.select_next_field
197
+ when 353
198
+ @form.select_prev_field
192
199
  else
193
200
  # fields must return unhandled else we will miss hotkeys.
194
201
  # On messageboxes, often if no edit field, then O and C are hot.
@@ -234,7 +241,7 @@ module RubyCurses
234
241
  # XXX this needs to go up and decide height of window
235
242
  if @message_height.nil?
236
243
  @message_height = (message.length/display_length)+1
237
- $log.debug " print_message: mh:#{@message_height}"
244
+ $log.debug " print_message: mh:#{@message_height}, ml: #{message.length}"
238
245
  end
239
246
  @message_height ||= 1
240
247
  width = @layout[:width]
@@ -251,6 +258,7 @@ module RubyCurses
251
258
  @message_col = (width-message.length)/2
252
259
  end
253
260
  @message_row = row
261
+ # FIXME : wont print if newline at end of message !!!
254
262
  #@window.printstring( row, @message_col , message, color=$reversecolor)
255
263
  # 2008-12-30 19:45 experimenting with label so we can get justify and wrapping.
256
264
  #@window.printstring( row, @message_col , message, color=$reversecolor)
@@ -264,6 +272,7 @@ module RubyCurses
264
272
  @message_col ||= 2
265
273
  r = @message_row + @message_height + 1
266
274
  c = @message_col
275
+ disp_len = @layout[:width]-8
267
276
  defaultvalue = @default_value || ""
268
277
  input_config = @config["input_config"] || {}
269
278
  case @type.to_s
@@ -272,7 +281,7 @@ module RubyCurses
272
281
  name "input"
273
282
  row r
274
283
  col c
275
- display_length 30
284
+ display_length disp_len
276
285
  set_buffer defaultvalue
277
286
  end
278
287
  when "list"
@@ -74,6 +74,9 @@ module RubyCurses
74
74
  include EventHandler
75
75
  dsl_accessor :row, :col
76
76
  dsl_accessor :height, :width
77
+ dsl_accessor :button_type # ok, ok_cancel, yes_no
78
+ dsl_accessor :buttons # used if type :custom
79
+ attr_reader :selected_index
77
80
  def initialize win, aconfig={}, &block
78
81
  @parent = win
79
82
  @tabs ||= []
@@ -161,6 +164,7 @@ module RubyCurses
161
164
  }
162
165
 
163
166
  end
167
+ create_buttons
164
168
  @form.repaint
165
169
  end
166
170
  def display_form form
@@ -183,7 +187,14 @@ module RubyCurses
183
187
  return form
184
188
  end
185
189
  def handle_keys
186
- while (( ch=@window.getchar()) != KEY_F1)
190
+ begin
191
+ while (( ch=@window.getchar()) != 999)
192
+ if ch == ?\C-q
193
+ @selected_index = -1 # this signifies cancel by ?C-q
194
+ @stop = true
195
+ return
196
+ end
197
+ return if @stop
187
198
  @current_form ||= @form
188
199
  ret = @current_form.handle_key(ch)
189
200
  case ret
@@ -220,15 +231,66 @@ module RubyCurses
220
231
  @form.repaint
221
232
  #return :UNHANDLED if ret == :UNHANDLED
222
233
  end
234
+ return if @stop
223
235
  @current_form.window.wrefresh
224
236
  @window.refresh
225
237
  end
226
- destroy
238
+ ensure
239
+ destroy
240
+ end
227
241
  end
228
242
  def destroy
229
243
  @window.destroy
230
244
  @forms.each { |f| w = f.window; w.destroy unless w.nil? }
231
245
  end
246
+ def create_buttons
247
+ case @button_type.to_s.downcase
248
+ when "ok"
249
+ make_buttons ["&OK"]
250
+ when "ok_cancel" #, "input", "list", "field_list"
251
+ make_buttons %w[&OK &Cancel]
252
+ when "yes_no"
253
+ make_buttons %w[&Yes &No]
254
+ when "yes_no_cancel"
255
+ make_buttons ["&Yes", "&No", "&Cancel"]
256
+ when "custom"
257
+ raise "Blank list of buttons passed to custom" if @buttons.nil? or @buttons.size == 0
258
+ make_buttons @buttons
259
+ else
260
+ $log.debug "No buttontype passed for creating tabbedpane. Using default (OK)"
261
+ make_buttons ["&OK"]
262
+ end
263
+ end
264
+ def make_buttons names
265
+ total = names.inject(0) {|total, item| total + item.length + 4}
266
+ bcol = center_column total
267
+
268
+ brow = @layout[:height]-2
269
+ button_ct=0
270
+ names.each_with_index do |bname, ix|
271
+ text = bname
272
+ #underline = @underlines[ix] if !@underlines.nil?
273
+
274
+ button = Button.new @form do
275
+ text text
276
+ name bname
277
+ row brow
278
+ col bcol
279
+ #underline underline
280
+ highlight_background $reversecolor
281
+ color $datacolor
282
+ bgcolor $datacolor
283
+ end
284
+ index = button_ct
285
+ button.command { |form| @selected_index = index; @stop = true; $log.debug "Pressed Button #{bname}";}
286
+ button_ct += 1
287
+ bcol += text.length+6
288
+ end
289
+ end
290
+ def center_column textlen
291
+ width = @layout[:width]
292
+ return (width-textlen)/2
293
+ end
232
294
 
233
295
  ##
234
296
  # nested class tab
@@ -4,7 +4,7 @@
4
4
  * Author: rkumar (arunachalesha)
5
5
 
6
6
 
7
- TODO: NOTE: Needs to be tested under conditions such as no data, deleting all data
7
+ TODO: NOTE:
8
8
  A few higher level methods check for no data but lower level ones do not.
9
9
 
10
10
  --------
@@ -78,7 +78,11 @@ module RubyCurses
78
78
  @toprow = 0
79
79
  @to_print_borders ||= 1
80
80
  @show_grid ||= 1
81
+ @_first_column_print = 0 # intro for horiz scrolling 2009-02-14 16:20
82
+ @_last_column_print = 0 # 2009-02-16 23:57 so we don't tab further etc.
83
+ # table needs to know what columns are being printed.
81
84
  @curpos = 0
85
+ @inter_column_spacing = 1
82
86
  # @selected_color ||= 'yellow'
83
87
  # @selected_bgcolor ||= 'black'
84
88
  @table_changed = true
@@ -112,6 +116,7 @@ module RubyCurses
112
116
  end
113
117
  # added 2009-01-07 13:05 so new scrollable can use
114
118
  def row_count
119
+ return 0 if @table_model.nil?
115
120
  @table_model.row_count
116
121
  end
117
122
  # added 2009-01-07 13:05 so new scrollable can use
@@ -123,17 +128,24 @@ module RubyCurses
123
128
  # Sets the data in models
124
129
  # Should replace if these are created. TODO FIXME
125
130
  def set_data data, colnames_array
131
+ # next 2 added in case set_data called again
132
+ @table_changed = true
133
+ @repaint_required = true
126
134
  if data.is_a? Array
127
135
  model = RubyCurses::DefaultTableModel.new data, colnames_array
128
136
  table_model model
129
137
  elsif data.is_a? RubyCurses::TableModel
130
138
  table_model data
139
+ else
140
+ raise "set_data: don't know how to handle data: #{data.class.to_s}"
131
141
  end
132
142
  if colnames_array.is_a? Array
133
143
  model = DefaultTableColumnModel.new colnames_array
134
144
  table_column_model model
135
145
  elsif colnames_array.is_a? RubyCurses::TableColumnModel
136
146
  table_column_model colnames_array
147
+ else
148
+ raise "set_data: don't know how to handle column data: #{colnames_array.class.to_s}"
137
149
  end
138
150
  create_default_list_selection_model
139
151
  create_table_header
@@ -164,8 +176,13 @@ module RubyCurses
164
176
  @table_model.bind(:TABLE_MODEL_EVENT){|lde| table_data_changed(lde) }
165
177
  end
166
178
  end
167
- def table_column_model tcm
168
- raise "data error" if !tcm.is_a? RubyCurses::TableColumnModel
179
+ # updated this so no param will return the tcm 2009-02-14 12:31
180
+ def table_column_model(*val)
181
+ if val.empty?
182
+ return @table_column_model
183
+ end
184
+ tcm = val[0]
185
+ raise "data error: table_column_model wrong class" if !tcm.is_a? RubyCurses::TableColumnModel
169
186
  @table_column_model = tcm
170
187
  @table_column_model.bind(:TABLE_COLUMN_MODEL_EVENT) {|e|
171
188
  table_structure_changed e
@@ -175,8 +192,9 @@ module RubyCurses
175
192
  #@table_header.column_model(tcm) unless @table_header.nil?
176
193
  @table_header.table_column_model=(tcm) unless @table_header.nil?
177
194
  end
178
- # FIX THIS SO NO GET_ XXX
195
+ # @deprecated, avoid usage
179
196
  def get_table_column_model
197
+ $log.debug " DEPRECATED. Pls use table_column_model()"
180
198
  @table_column_model
181
199
  end
182
200
  #
@@ -381,11 +399,16 @@ module RubyCurses
381
399
  end
382
400
  end
383
401
  editor = get_default_cell_editor_for_class cls
402
+ #$log.debug "EDIT_CELL_AT:1 #{cls} #{editor.component.display_length} = #{@table_column_model.column(col).width}i maxlen #{editor.component.maxlen}"
384
403
  editor.component.display_length = @table_column_model.column(col).width
385
- editor.component.maxlen = editor.component.display_length if editor.component.respond_to? :maxlen and editor.component.maxlen.nil? # 2009-01-18 00:59 XXX don't overwrite if user has set
404
+ # maxlen won't be nil ! This used to work earlier
405
+ #editor.component.maxlen = editor.component.display_length if editor.component.respond_to? :maxlen and editor.component.maxlen.nil? # 2009-01-18 00:59 XXX don't overwrite if user has set
406
+ if editor.component.respond_to? :maxlen
407
+ editor.component.maxlen = @table_column_model.column(col).edit_length || editor.component.display_length
408
+ end
386
409
  #$log.debug "EDIT_CELL_AT: #{cls} #{editor.component.display_length} = #{@table_column_model.column(col).width}i maxlen #{editor.component.maxlen}"
387
410
  end
388
- $log.debug " got an EDITOR #{editor} :: #{editor.component} "
411
+ #$log.debug " got an EDITOR #{editor} :: #{editor.component} "
389
412
  # by now we should have something to edit with. We just need to prepare the widgey.
390
413
  prepare_editor editor, row, col, value
391
414
 
@@ -395,6 +418,14 @@ module RubyCurses
395
418
  row = r + (row - @toprow) +1 # @form.row , 1 added for header row!
396
419
  col = c+get_column_offset()
397
420
  editor.prepare_editor self, row, col, value
421
+ # added on 2009-02-16 23:49
422
+ # if data is longer than can be displayed then update editors disp len too
423
+ if (col+editor.component.display_length)>= @col+@width
424
+ editor.component.display_length = @width-1-col
425
+ $log.debug "DDDXXX #{editor.component.display_length} = @width-1-col"
426
+ else
427
+ $log.debug "EEE if (#{col+editor.component.display_length})> #{@col+@width}"
428
+ end
398
429
  @cell_editor = editor
399
430
  @repaint_required = true
400
431
  set_form_col
@@ -452,6 +483,7 @@ module RubyCurses
452
483
  # key handling
453
484
  # make separate methods so callable programmatically
454
485
  def handle_key(ch)
486
+ return :UNHANDLED if @table_model.nil?
455
487
  @current_index ||= 0
456
488
  @toprow ||= 0
457
489
  h = scrollatrow()
@@ -494,6 +526,12 @@ module RubyCurses
494
526
  when @KEY_GOTO_BOTTOM
495
527
  editing_stopped if @is_editing # 2009-01-16 16:06
496
528
  goto_bottom
529
+ when @KEY_SCROLL_RIGHT
530
+ editing_stopped if @is_editing # dts 2009-02-17 00:35
531
+ scroll_right
532
+ when @KEY_SCROLL_LEFT
533
+ editing_stopped if @is_editing # dts 2009-02-17 00:35
534
+ scroll_left
497
535
  else
498
536
  # there could be a case of editing here too!
499
537
  ret = process_key ch, self
@@ -565,14 +603,16 @@ module RubyCurses
565
603
  end
566
604
  def next_column
567
605
  v = @current_column+1
568
- if v < @table_column_model.column_count
606
+ if v < @table_column_model.column_count and v <= @_last_column_print
569
607
  $log.debug " if v < #{@table_column_model.column_count} "
570
608
  current_column v
571
609
  else
572
- if @current_index < row_count()-1
610
+ if @current_index < row_count()-1
573
611
  $log.debug " GOING TO NEXT ROW FROM NEXT COL : #{@current_index} : #{row_count}"
574
612
  @current_column = 0
613
+ @current_column = @_first_column_print # added 2009-02-17 00:01
575
614
  next_row
615
+ set_form_col
576
616
  else
577
617
  return :UNHANDLED
578
618
  end
@@ -581,11 +621,14 @@ module RubyCurses
581
621
  def previous_column
582
622
  v = @current_column-1
583
623
  # returning unhandled so focus can go to prev field auto
584
- if v < 0 and @current_index <= 0
624
+ if v < @_first_column_print and @current_index <= 0
585
625
  return :UNHANDLED
586
626
  end
587
- if v < 0 and @current_index > 0
627
+ if v < @_first_column_print and @current_index > 0
588
628
  @current_column = @table_column_model.column_count-1
629
+ @current_column = @_last_column_print # added 2009-02-17 00:01
630
+ $log.debug " XXXXXX prev col #{@current_column}, las #{@_last_column_print}, fi: #{@_first_column_print}"
631
+ set_form_col
589
632
  previous_row
590
633
  else
591
634
  current_column @current_column-1
@@ -693,7 +736,7 @@ module RubyCurses
693
736
  super
694
737
  set_form_row
695
738
  set_form_col # 2009-01-17 01:35
696
- on_enter_cell focussed_row(), focussed_col()
739
+ on_enter_cell focussed_row(), focussed_col() unless focussed_row().nil? or focussed_col().nil?
697
740
  end
698
741
  def on_leave
699
742
  super
@@ -713,6 +756,7 @@ module RubyCurses
713
756
  end
714
757
  # protected
715
758
  def get_column_offset columnid=@current_column
759
+ return 0 if @table_column_model.nil?
716
760
  return @table_column_model.column(columnid).column_offset || 0
717
761
  end
718
762
 
@@ -720,11 +764,16 @@ module RubyCurses
720
764
  def repaint
721
765
  return unless @repaint_required
722
766
  print_border @form.window if @to_print_borders == 1 # do this once only, unless everything changes
767
+ return if @table_model.nil? # added 2009-02-17 12:45
768
+ @_first_column_print ||= 0
723
769
  cc = @table_model.column_count
724
770
  rc = @table_model.row_count
771
+ inter_column_padding = " " * @inter_column_spacing
772
+ @_last_column_print = cc-1
725
773
  tcm = @table_column_model
726
774
  tm = @table_model
727
775
  tr = @toprow
776
+ _column_scrolling = false
728
777
  acolor = get_color $datacolor
729
778
  h = scrollatrow()
730
779
  r,c = rowcol
@@ -734,18 +783,19 @@ module RubyCurses
734
783
  # TCM should give modelindex of col which is used to fetch data from TM
735
784
  r += 1 # save for header
736
785
  0.upto(h) do |hh|
737
- crow = tr+hh
786
+ crow = tr+hh # crow is the row
738
787
  if crow < rc
739
- offset = 0
788
+ offset = 0 # offset of column
740
789
  # 0.upto(cc-1) do |colix|
790
+ focussed = @current_index == crow ? true : false
791
+ selected = is_row_selected crow
741
792
  # we loop through column_model and fetch data based on model index
742
793
  # FIXED better to call table.get_value_at since we may now
743
794
  # introduce a view - 2009-01-18 18:21
744
795
  tcm.each_with_index do |acolumn, colix|
796
+ next if colix < @_first_column_print
745
797
  #acolumn = tcm.column(colix)
746
798
  #model_index = acolumn.model_index
747
- focussed = @current_index == crow ? true : false
748
- selected = is_row_selected crow
749
799
  content = get_value_at(crow, colix) # tables
750
800
  #renderer = get_default_cell_renderer_for_class content.class.to_s
751
801
  renderer = get_cell_renderer(crow, colix)
@@ -753,9 +803,33 @@ module RubyCurses
753
803
  renderer = get_default_cell_renderer_for_class(content.class.to_s) if renderer.nil?
754
804
  renderer.display_length acolumn.width unless acolumn.nil?
755
805
  end
756
- width = renderer.display_length + 1
806
+ width = renderer.display_length + @inter_column_spacing
757
807
  #renderer.repaint @form.window, r+hh, c+(colix*11), content, focussed, selected
758
808
  acolumn.column_offset = offset
809
+ # trying to ensure that no overprinting
810
+ # $log.debug " c+offset+width > @col+@width #{c+offset+width} > #{@col}+#{@width}"
811
+ # $log.debug " #{c}+#{offset}+#{width} > @col+@width #{c+offset+width} > #{@col}+#{@width}"
812
+ if c+offset+width > @col+@width
813
+ _column_scrolling = true
814
+ @_last_column_print = colix
815
+ #$log.debug " TABLE BREAKING SINCE "
816
+ #$log.debug " if c+offset+width > @col+@width #{c+offset+width} > #{@col}+#{@width}"
817
+ #$log.debug " if #{c}+#{offset}+#{width} > @col+@width #{c+offset+width} > #{@col}+#{@width}"
818
+ # experimental to print subset of last
819
+ space_left = (@width-3)-(offset) # 3 due to boundaries
820
+ space_left = 0 if space_left < 0
821
+ if content.length > space_left
822
+ clen = space_left
823
+ renderer.display_length clen
824
+ else
825
+ clen = -1
826
+ renderer.display_length space_left # content.length
827
+ end
828
+ # print the inter cell padding just in case things mess up while scrolling
829
+ @form.window.mvprintw r+hh, c+offset-@inter_column_spacing, inter_column_padding
830
+ renderer.repaint @form.window, r+hh, c+offset, crow, content[0..clen], focussed, selected
831
+ break
832
+ end
759
833
  # added crow on 2009-02-11 22:46
760
834
  renderer.repaint @form.window, r+hh, c+(offset), crow, content, focussed, selected
761
835
  offset += width
@@ -768,12 +842,33 @@ module RubyCurses
768
842
  if @is_editing
769
843
  @cell_editor.component.repaint unless @cell_editor.nil? or @cell_editor.component.form.nil?
770
844
  end
845
+ _print_more_columns_marker _column_scrolling
846
+ _print_more_data_marker(rc-1 > tr + h)
847
+ $log.debug " _print_more_data_marker(#{rc} >= #{tr} + #{h})"
771
848
  @table_changed = false
772
849
  @repaint_required = false
773
850
  end
774
851
  def print_border g
775
852
  return unless @table_changed
776
853
  g.print_border @row, @col, @height, @width, $datacolor
854
+ return if @table_model.nil?
855
+ rc = @table_model.row_count
856
+ h = scrollatrow()
857
+ _print_more_data_marker (rc>h)
858
+ end
859
+ # private
860
+ def _print_more_data_marker tf
861
+ marker = tf ? Ncurses::ACS_CKBOARD : Ncurses::ACS_VLINE
862
+ @form.window.mvwaddch @row+@height-1, @col+@width-1, marker
863
+ marker = @toprow > 0 ? Ncurses::ACS_CKBOARD : Ncurses::ACS_VLINE
864
+ @form.window.mvwaddch @row+1, @col+@width-1, marker
865
+ end
866
+ def _print_more_columns_marker tf
867
+ marker = tf ? Ncurses::ACS_CKBOARD : Ncurses::ACS_HLINE
868
+ @form.window.mvwaddch @row+@height, @col+@width-2, marker
869
+ # show if columns to left or not
870
+ marker = @_first_column_print > 0 ? Ncurses::ACS_CKBOARD : Ncurses::ACS_HLINE
871
+ @form.window.mvwaddch @row+@height, @col+@_first_column_print+1, marker
777
872
  end
778
873
  def print_header
779
874
  return unless @table_changed
@@ -782,12 +877,29 @@ module RubyCurses
782
877
  tcm = @table_column_model ## could have been overridden, should we use this at all
783
878
  offset = 0
784
879
  header_model.each_with_index do |tc, colix|
880
+ next if colix < @_first_column_print # added for scrolling rt and left 2009-02-14 17:49
785
881
  acolumn = tcm.column colix
786
882
  renderer = tc.cell_renderer
787
883
  renderer = @table_header.default_renderer if renderer.nil?
788
884
  renderer.display_length acolumn.width unless acolumn.nil?
789
885
  width = renderer.display_length + 1
790
886
  content = tc.header_value
887
+ if c+offset+width > @col+@width
888
+ #$log.debug " TABLE: experimental code to NOT print if chance of exceeding table width"
889
+ # 2009-02-14 14:24 now printing, but truncating data for last column
890
+ space_left = (@width-3)-(offset)
891
+ space_left = 0 if space_left < 0
892
+ if content.length > space_left
893
+ clen = space_left
894
+ renderer.display_length clen
895
+ else
896
+ clen = -1
897
+ renderer.display_length space_left
898
+ end
899
+ #$log.debug " TABLE BREAKING SINCE sl: #{space_left},#{crow},#{colix}: #{clen} "
900
+ renderer.repaint @form.window, r, c+(offset), 0, content[0..clen], false, false
901
+ break
902
+ end
791
903
  renderer.repaint @form.window, r, c+(offset),0, content, false, false
792
904
  offset += width
793
905
  end
@@ -837,6 +949,97 @@ module RubyCurses
837
949
  set_focus_on(ix)
838
950
  end
839
951
  end
952
+ def scroll_right
953
+ cc = @table_model.column_count
954
+ if @_first_column_print < cc-1
955
+ @_first_column_print += 1
956
+ @current_column = @_first_column_print
957
+ set_form_col # FIXME not looking too good till key press
958
+ @repaint_required = true
959
+ @table_changed = true # so columns are modified
960
+ end
961
+ end
962
+ def scroll_left
963
+ if @_first_column_print > 0
964
+ @_first_column_print -= 1
965
+ @current_column = @_first_column_print
966
+ set_form_col
967
+ @repaint_required = true
968
+ @table_changed = true
969
+ end
970
+ end
971
+ ##
972
+ # Makes an estimate of columns sizes, returning a hash, and storing it as @column_widths
973
+ # based on checking first 20 rows of data.
974
+ # This does not try to fit all columns into table, but gives best width, so you
975
+ # can scroll right to see other columns.
976
+ # @params - columns is columns returned by database
977
+ # using the command: @columns, *rows = @db.execute2(command)
978
+ # @param - datatypes is an array returned by following command to DB
979
+ # @datatypes = @content[0].types
980
+ def estimate_column_widths columns, datatypes
981
+ tablewidth = @width-3
982
+ colwidths = {}
983
+ min_column_width = (tablewidth/columns.length) -1
984
+ $log.debug("min: #{min_column_width}, #{tablewidth}")
985
+ 0.upto(20) do |rowix|
986
+ break if rowix >= row_count
987
+ #@content.each_with_index do |row, cix|
988
+ # break if cix >= 20
989
+ @table_column_model.each_with_index do |acolumn, ix|
990
+ col = get_value_at(rowix, ix)
991
+ colwidths[ix] ||= 0
992
+ colwidths[ix] = [colwidths[ix], col.length].max
993
+ end
994
+ end
995
+ total = 0
996
+ colwidths.each_pair do |k,v|
997
+ name = columns[k.to_i]
998
+ colwidths[name] = v
999
+ total += v
1000
+ end
1001
+ colwidths["__TOTAL__"] = total
1002
+ column_widths = colwidths
1003
+ @max_data_widths = column_widths.dup
1004
+
1005
+ columns.each_with_index do | col, i|
1006
+ if datatypes[i].match(/(real|int)/) != nil
1007
+ wid = column_widths[i]
1008
+ # cw = [column_widths[i], [8,min_column_width].min].max
1009
+ $log.debug("XXX #{wid}. #{columns[i].length}")
1010
+ cw = [wid, columns[i].length].max
1011
+ $log.debug("int #{col} #{column_widths[i]}, #{cw}")
1012
+ elsif datatypes[i].match(/(date)/) != nil
1013
+ cw = [column_widths[i], [12,min_column_width].min].max
1014
+ #cw = [12,min_column_width].min
1015
+ $log.debug("date #{col} #{column_widths[i]}, #{cw}")
1016
+ else
1017
+ cw = [column_widths[i], min_column_width].max
1018
+ if column_widths[i] <= col.length and col.length <= min_column_width
1019
+ cw = col.length
1020
+ end
1021
+ $log.debug("else #{col} #{column_widths[i]}, #{col.length} #{cw}")
1022
+ end
1023
+ column_widths[i] = cw
1024
+ total += cw
1025
+ end
1026
+ column_widths["__TOTAL__"] = total
1027
+ $log.debug("Estimated col widths: #{column_widths.inspect}")
1028
+ @column_widths = column_widths
1029
+ return column_widths
1030
+ end
1031
+ ##
1032
+ # convenience method
1033
+ # sets column widths given an array of ints
1034
+ # You may get such an array from estimate_column_widths
1035
+ def set_column_widths cw
1036
+ tcm = @table_column_model
1037
+ tcm.each_with_index do |col, ix|
1038
+ col.width cw[ix]
1039
+ end
1040
+ table_structure_changed(nil)
1041
+ end
1042
+ # ADD METHODS HERE
840
1043
  end # class Table
841
1044
 
842
1045
  ## TC
@@ -863,6 +1066,7 @@ module RubyCurses
863
1066
  ## added column_offset on 2009-01-12 19:01
864
1067
  attr_accessor :column_offset # where we've place this guy. in case we need to position cursor
865
1068
  attr_accessor :cell_editor
1069
+ dsl_accessor :edit_length # corresponds to maxlen, if not set, col width will be useda 2009-02-16 21:55
866
1070
 
867
1071
 
868
1072
  def initialize model_index, identifier, header_value, width, config={}, &block
@@ -1161,8 +1365,8 @@ module RubyCurses
1161
1365
 
1162
1366
  ##
1163
1367
  # LSM
1164
- #
1165
- class DefaultListSelectionModel
1368
+ # XXX UNUSED
1369
+ class OLDDefaultListSelectionModel
1166
1370
  include RubyCurses::EventHandler
1167
1371
  attr_accessor :selection_mode
1168
1372
  attr_reader :anchor_selection_index
@@ -1172,6 +1376,7 @@ module RubyCurses
1172
1376
  @anchor_selection_index = -1
1173
1377
  @lead_selection_index = -1
1174
1378
  @selection_mode = :MULTIPLE
1379
+ $log.debug " OLD VERSION OF LIST SELECTION MODEL IN rtable.rb"
1175
1380
  end
1176
1381
 
1177
1382
  def clear_selection