Class: RubyCurses::Table

Inherits:
Widget
  • Object
show all
Includes:
ListKeys, ListSelectable
Defined in:
lib/rbcurse/rtable.rb

Overview

—— NOTE —————— # Table contains a TableModel Table contains a TableColumnModel (which contains TableColumn instances) TableColumn contains 2 TableCellRenderer: column and header ———————— #

Due to not having method overloading, after usig new, use set_data or set_model

This is a widget that displays tabular data. We will get into editing after this works out. This uses the MVC architecture and is WIP as of 2009-01-04 18:37 TODO cellrenderers should be able to get parents bgcolor and color (Jtables) if none defined for them.

Constant Summary

Constants included from Io

Io::ERROR_COLOR_PAIR, Io::FOOTER_COLOR_PAIR, Io::LINEONE, Io::MAIN_WINDOW_COLOR_PAIR

Instance Attribute Summary collapse

Attributes included from ListSelectable

#column_selection_allowed, #row_selection_allowed

Attributes inherited from Widget

#col_offset, #cols_panned, #config, #curpos, #ext_col_offset, #ext_row_offset, #form, #id, #parent_component, #row_offset, #rows_panned, #should_create_buffer, #state

Instance Method Summary collapse

Methods included from ListKeys

#install_list_keys

Methods included from ListSelectable

#add_row_selection_interval, #clear_selection, #create_default_list_selection_model, #do_next_selection, #do_prev_selection, #is_row_selected, #list_selection_model, #remove_row_selection_interval, #selected_item, #selected_row, #selected_row_count, #selected_rows, #toggle_row_selection

Methods inherited from Widget

#OLDbind_key, #buffer_to_screen, #buffer_to_window, #create_buffer, #destroy, #destroy_buffer, #focus, #get_buffer, #get_color, #get_preferred_size, #getvalue, #getvalue_for_paint, #height, #height=, #hide, #is_double_buffered?, #modified?, #move, #override_graphic, #process_key, #remove, #repaint_all, #repaint_required, #rowcol, #safe_create_buffer, #set_buffer_modified, #set_buffering, #set_form, #set_modified, #setformrowcol, #setrowcol, #show, #text_variable, #unbind_key, #width, #width=

Methods included from Io

#askchoice, #askyesno, #askyesnocancel, #clear_error, #clear_this, #get_string, #newaskyesno, #old_print_header, #old_print_top_right, #print_action, #print_error, #print_footer_help, #print_headers, #print_help, #print_help_page, #print_in_middle, #print_key_labels, #print_key_labels_row, #print_screen_labels, #print_status, #print_this, #print_top_right, #rbgetstr

Methods included from Utils

#_process_key, #bind_key, #clean_string!, #get_color, #keycode_tos, #repeatm, #wrap_text

Methods included from ConfigSetup

#cget, #config_setup, #configure, #variable_set

Methods included from EventHandler

#bind, #fire_handler, #fire_property_change

Methods included from DSL

#OLD_method_missing

Constructor Details

#initialize(form = nil, config = {}, &block) ⇒ Table

Returns a new instance of Table.



74
75
76
77
78
79
80
# File 'lib/rbcurse/rtable.rb', line 74

def initialize form = nil, config={}, &block
  super
  init_vars
  install_list_keys
  install_keys_bindings
  ## create_buffer needs to move to repaint. widget needs values to use when i creates buffer in repaint.
end

Instance Attribute Details

#current_indexObject

the row index universally



62
63
64
# File 'lib/rbcurse/rtable.rb', line 62

def current_index
  @current_index
end

#editing_colObject (readonly)

attr_accessor :current_column # index of column (usually in current row ) a changed event of an editor component can utitlize this if it wishes to know the row or col that was exited.



66
67
68
# File 'lib/rbcurse/rtable.rb', line 66

def editing_col
  @editing_col
end

#editing_rowObject (readonly)

attr_accessor :current_column # index of column (usually in current row ) a changed event of an editor component can utitlize this if it wishes to know the row or col that was exited.



66
67
68
# File 'lib/rbcurse/rtable.rb', line 66

def editing_row
  @editing_row
end

#is_editingObject

boolean is only true if cell_editing_allowed



67
68
69
# File 'lib/rbcurse/rtable.rb', line 67

def is_editing
  @is_editing
end

#toprowObject

top visible



1039
1040
1041
# File 'lib/rbcurse/rtable.rb', line 1039

def toprow
  @toprow
end

Instance Method Details

#_print_more_columns_marker(tf) ⇒ Object



986
987
988
989
990
991
992
# File 'lib/rbcurse/rtable.rb', line 986

def _print_more_columns_marker tf
  marker = tf ?  Ncurses::ACS_CKBOARD : Ncurses::ACS_HLINE
  @graphic.mvwaddch @row+@height-1, @col+@width-2, marker
  # show if columns to left or not
  marker = @_first_column_print > 0 ?  Ncurses::ACS_CKBOARD : Ncurses::ACS_HLINE
  @graphic.mvwaddch @row+@height-1, @col+@_first_column_print+1, marker
end

#_print_more_data_marker(tf) ⇒ Object

private



980
981
982
983
984
985
# File 'lib/rbcurse/rtable.rb', line 980

def _print_more_data_marker tf
  marker = tf ?  Ncurses::ACS_CKBOARD : Ncurses::ACS_VLINE
  @graphic.mvwaddch @row+@height-2, @col+@width-1, marker
  marker = @toprow > 0 ?  Ncurses::ACS_CKBOARD : Ncurses::ACS_VLINE
  @graphic.mvwaddch @row+1, @col+@width-1, marker
end

#add_column(tc) ⇒ Object



278
279
280
281
# File 'lib/rbcurse/rtable.rb', line 278

def add_column tc
  @table_column_model << tc
  #table_structure_changed # this should be called by tcm TODO with object
end

#add_column_selection_interval(ix0, ix1) ⇒ Object



237
238
239
240
# File 'lib/rbcurse/rtable.rb', line 237

def add_column_selection_interval ix0, ix1
  raise "TODO "
  # if column_selection_allowed
end

#ask_search_backwardObject



1040
1041
1042
1043
1044
1045
1046
1047
1048
# File 'lib/rbcurse/rtable.rb', line 1040

def ask_search_backward
  regex =  get_string("Enter regex to search (backward)")
  ix = @table_model.find_prev regex, @current_index
  if ix.nil?
    alert("No matching data for: #{regex}")
  else
    set_focus_on(ix)
  end
end

#ask_search_forwardObject



1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
# File 'lib/rbcurse/rtable.rb', line 1058

def ask_search_forward
  regex =  get_string("Enter regex to search (forward)")
  #ix = @table_model.find_next regex, @current_index
  ix = @table_model.find_match regex, @current_index
  if ix.nil?
    alert("No matching data for: #{regex}")
  else
    set_focus_on(ix)
  end
end

#bounds_checkObject



746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
# File 'lib/rbcurse/rtable.rb', line 746

def bounds_check
  h = scrollatrow()
  rc = row_count
  #$log.debug " PRE CURR:#{@current_index}, TR: #{@toprow} RC: #{rc} H:#{h}"
  @current_index = 0 if @current_index < 0  # not lt 0
  @current_index = rc-1 if @current_index >= rc # not gt rowcount
  @toprow = rc-h-1 if rc > h and @toprow > rc - h - 1 # toprow shows full page if possible
  # curr has gone below table,  move toprow forward
  if @current_index - @toprow > h
    @toprow = @current_index - h
  elsif @current_index < @toprow
    # curr has gone above table,  move toprow up
    @toprow = @current_index
  end
  #$log.debug " POST CURR:#{@current_index}, TR: #{@toprow} RC: #{rc} H:#{h}"
  if @oldrow != @current_index
    #$log.debug "going to call on leave and on enter"
    on_leave_row @oldrow #if respond_to? :on_leave_row     # to be defined by widget that has included this
    on_enter_row @current_index   #if respond_to? :on_enter_row  # to be defined by widget that has included this
  end
  set_form_row
  @oldrow = @current_index # added 2009-01-16 19:43 XXX
  @repaint_required = true
end

#cancel_editorObject

Its too late to call components on_leave here since cursor would have moved elsewhere. Prior to moving out of a field, the on_leave should be called and exceptions caught FIXME



464
465
466
467
468
469
470
# File 'lib/rbcurse/rtable.rb', line 464

def cancel_editor
  # not really required, the refresh was required. Ok, now i call components on_leave inside
  #@cell_editor.cancel_editor
  @editing_row, @editing_col = nil, nil
  @is_editing = false
  @repaint_required = true
end

#column(ix) ⇒ Object

returns col by col ix added on 2009-01-16 23:45



292
293
294
# File 'lib/rbcurse/rtable.rb', line 292

def column ix
  @table_column_model.column(ix)
end

#column_property_changed(evt) ⇒ Object



341
342
343
344
345
# File 'lib/rbcurse/rtable.rb', line 341

def column_property_changed evt
  $log.debug "JT def column_property_changed #{evt} "
  @table_changed = true
  @repaint_required = true
end

#create_default_table_column_modelObject



223
224
225
# File 'lib/rbcurse/rtable.rb', line 223

def create_default_table_column_model
  table_column_model DefaultTableColumnModel.new
end

#create_table_headerObject



226
227
228
# File 'lib/rbcurse/rtable.rb', line 226

def create_table_header
  @table_header = TableHeader.new @table_column_model
end

#current_column(*val) ⇒ Object

getter and setter for current_column index



259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
# File 'lib/rbcurse/rtable.rb', line 259

def current_column(*val)
  if val.empty?
    @current_column || 0
  else
    @oldcol = @current_column
    v = val[0]
    v = 0 if v < 0
    v = @table_column_model.column_count-1 if v > @table_column_model.column_count-1
    @current_column = v 
    if @current_column != @oldcol
      on_leave_column @oldcol
      on_enter_column @current_column
    end
    set_form_col
    @oldcol = @current_column # added on 2009-01-16 19:40 for next_col
  end
end

#edit_cell_at(row, col) ⇒ Object



397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
# File 'lib/rbcurse/rtable.rb', line 397

def edit_cell_at row, col
  acolumn = column(col)
  if acolumn.editable == false or (acolumn.editable.nil? and @cell_editing_allowed!=true)
    $log.debug " editing not allowed in #{col}"
    @is_editing = false
    return nil
  end
  return nil if row >= row_count
  value = get_value_at row, col
  editor = get_cell_editor row, col
  @old_cell_value = value # for event
  if editor.nil?
    
    cls = value.nil? ? get_value_at(0,col).class.to_s : value.class.to_s
    if value.nil?
      case cls
      when 'String'
        value = value.to_s
      when 'Fixnum'
        value = value.to_i
      when 'Float'
        value = value.to_f
      else
        value = value.to_s
      end
    end
    editor = get_default_cell_editor_for_class cls
    #$log.debug "EDIT_CELL_AT:1 #{cls}  #{editor.component.display_length} = #{@table_column_model.column(col).width}i maxlen #{editor.component.maxlen}"
    editor.component.display_length = @table_column_model.column(col).width
    # maxlen won't be nil ! This used to work earlier
    #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
    if editor.component.respond_to? :maxlen 
      editor.component.maxlen = @table_column_model.column(col).edit_length || editor.component.display_length 
    end
    #$log.debug "EDIT_CELL_AT: #{cls}  #{editor.component.display_length} = #{@table_column_model.column(col).width}i maxlen #{editor.component.maxlen}"
  end
  #$log.debug " got an EDITOR #{editor} ::  #{editor.component} "
  # by now we should have something to edit with. We just need to prepare the widgey.
  prepare_editor editor, row, col, value

end

#editing_canceledObject



576
577
578
579
580
# File 'lib/rbcurse/rtable.rb', line 576

def editing_canceled
  return unless @cell_editing_allowed
  @is_editing = false if @is_editing
  cancel_editor
end

#editing_startedObject



590
591
592
593
594
595
596
597
598
599
600
# File 'lib/rbcurse/rtable.rb', line 590

def editing_started
  return if !@cell_editing_allowed or row_count < 1
  @is_editing = true # 2009-01-16 16:14 
  $log.debug " turning on editing cell at #{focussed_row}, #{focussed_col}"
  # on deleting last row, we need to go back 2009-01-19 18:31 
  if focussed_row >= row_count
    bounds_check
  end
  @editing_row, @editing_col = focussed_row(), focussed_col()
  edit_cell_at focussed_row(), focussed_col()
end

#editing_stopped(row = focussed_row(), col = focussed_col()) ⇒ Object

EDST the defualt values are useful when user is ON the field and pressed ENTER when leaving a cell, this should have oldrow and oldcol, not default values this throws an exception if validation on field fails NOTE



605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
# File 'lib/rbcurse/rtable.rb', line 605

def editing_stopped row=focussed_row(), col=focussed_col()
  return unless @cell_editing_allowed or @is_editing == false or column(col).editable == false
  return if row_count < 1
  $log.debug "editing_stopped set_value_at(#{row}, #{col}: #{@cell_editor.getvalue}"
  # next line should be in on_leave_cell but that's not being called FIXME from everywhere
  @cell_editor.on_leave row,col # added here since this is called whenever a cell is exited

  value = @cell_editor.getvalue
  if value != @old_cell_value
    set_value_at(row, col, @cell_editor.getvalue) #.dup 2009-01-10 21:42 boolean can't duplicate
    if @table_editing_event.nil? 
      @table_editing_event ||= TableEditingEvent.new row, col, self, @old_cell_value, value, :EDITING_STOPPED
    else
      @table_editing_event.set row, col, self, @old_cell_value, value, :EDITING_STOPPED
    end
    fire_handler :TABLE_EDITING_EVENT, @table_editing_event
  end
  cancel_editor
end

#estimate_column_widths(columns, datatypes) ⇒ Object

Makes an estimate of columns sizes, returning a hash, and storing it as @column_widths based on checking first 20 rows of data. This does not try to fit all columns into table, but gives best width, so you can scroll right to see other columns. using the command: @columns, *rows = @db.execute2(command)

Parameters:

  • -

    datatypes is an array returned by following command to DB



1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
# File 'lib/rbcurse/rtable.rb', line 1107

def estimate_column_widths columns, datatypes
  tablewidth = @width-3
  colwidths = {}
  min_column_width = (tablewidth/columns.length) -1
  $log.debug("min: #{min_column_width}, #{tablewidth}")
  0.upto(20) do |rowix|
    break if rowix >= row_count
  #@content.each_with_index do |row, cix|
  #  break if cix >= 20
    @table_column_model.each_with_index do |acolumn, ix|
      col = get_value_at(rowix, ix)
      colwidths[ix] ||= 0
      colwidths[ix] = [colwidths[ix], col.length].max
    end
  end
  total = 0
  # crashing in 1.9.2 due to hash key no insert in iteration 2010-08-22 20:09 
  #colwidths.each_pair do |k,v|
  tkeys = colwidths.keys
  tkeys.each do |k|
    name = columns[k.to_i]
    v = colwidths[k]
    colwidths[name] = v
    total += v
  end
  colwidths["__TOTAL__"] = total
  column_widths = colwidths
  @max_data_widths = column_widths.dup

  columns.each_with_index do | col, i|
  if datatypes[i].match(/(real|int)/) != nil
    wid = column_widths[i]
    #   cw = [column_widths[i], [8,min_column_width].min].max
    $log.debug("XXX #{wid}. #{columns[i].length}")
    cw = [wid, columns[i].length].max
    $log.debug("int #{col} #{column_widths[i]}, #{cw}")
  elsif datatypes[i].match(/(date)/) != nil
    cw = [column_widths[i], [12,min_column_width].min].max
    #cw = [12,min_column_width].min
    $log.debug("date #{col}  #{column_widths[i]}, #{cw}")
  else
    cw = [column_widths[i], min_column_width].max
    if column_widths[i] <= col.length and col.length <= min_column_width
      cw = col.length
    end
    $log.debug("else #{col} #{column_widths[i]}, #{col.length} #{cw}")
  end
  column_widths[i] = cw
  total += cw
  end
  column_widths["__TOTAL__"] = total
  $log.debug("Estimated col widths: #{column_widths.inspect}")
  @column_widths = column_widths
  return column_widths
end

#find_nextObject

table find_next



1069
1070
1071
1072
1073
1074
1075
1076
1077
# File 'lib/rbcurse/rtable.rb', line 1069

def find_next 
  ix = @table_model.find_next
  regex = @table_model.last_regex 
  if ix.nil?
    alert("No more matching data for: #{regex}")
  else
    set_focus_on(ix)
  end
end

#find_prevObject



1049
1050
1051
1052
1053
1054
1055
1056
1057
# File 'lib/rbcurse/rtable.rb', line 1049

def find_prev 
  ix = @table_model.find_prev
  regex = @table_model.last_regex 
  if ix.nil?
    alert("No previous matching data for: #{regex}")
  else
    set_focus_on(ix)
  end
end

#focussed_colObject



133
134
135
136
137
# File 'lib/rbcurse/rtable.rb', line 133

def focussed_col
  return nil if row_count < 1
  #raise "No data in table" if row_count < 1
  @current_column
end

#focussed_rowObject



128
129
130
131
132
# File 'lib/rbcurse/rtable.rb', line 128

def focussed_row
  #raise "No data in table" if row_count < 1
  return nil if row_count < 1
  @current_index
end

#get_cell_editor(row, col) ⇒ Object

——- editing methods———- #



390
391
392
393
394
395
396
# File 'lib/rbcurse/rtable.rb', line 390

def get_cell_editor row, col
$log.debug " def get_cell_editor #{row}, #{col}"
  column = @table_column_model.column(col)
  return nil if column.editable == false or (column.editable.nil? and @cell_editing_allowed!=true)
  editor = column.cell_editor
  return editor # can be nil
end

#get_cell_renderer(row, col) ⇒ Object

override for cell or row behaviour



382
383
384
385
386
387
# File 'lib/rbcurse/rtable.rb', line 382

def get_cell_renderer row, col
  # get columns renderer else class default
  column = @table_column_model.column(col)
  rend = column.cell_renderer
  return rend # can be nil
end

#get_column(identifier) ⇒ Object

table_structure_changed # this should be called by tcm TODO with object



286
287
288
289
# File 'lib/rbcurse/rtable.rb', line 286

def get_column identifier
  ix = @table_column_model.column_index identifier
  return @table_column_model.column ix
end

#get_column_name(ix) ⇒ Object



295
296
297
# File 'lib/rbcurse/rtable.rb', line 295

def get_column_name ix
  @table_column_model.column(ix).identifier
end

#get_column_offset(columnid = @current_column) ⇒ Object

protected



844
845
846
847
# File 'lib/rbcurse/rtable.rb', line 844

def get_column_offset columnid=@current_column
  return 0 if @table_column_model.nil?
  return @table_column_model.column(columnid).column_offset || 0
end

#get_default_cell_editor_for_class(cname) ⇒ Object



471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
# File 'lib/rbcurse/rtable.rb', line 471

def get_default_cell_editor_for_class cname
  @ceh ||= {}
  cname = 'Boolean' if cname == 'TrueClass' or cname == 'FalseClass'
  if @ceh.include? cname
    return @ceh[cname]
  else
    case cname
    when 'String'
      # I do not know cell width here, you will have toset display_length NOTE
      ce = RubyCurses::CellEditor.new RubyCurses::Field.new nil, {"focusable"=>false, "visible"=>false, "display_length"=> 8, :name => "tb_field_str"}
      @ceh['String'] = ce
      return ce
    when 'Fixnum'
      ce = RubyCurses::CellEditor.new RubyCurses::Field.new nil, {"focusable"=>false, "visible"=>false, "display_length"=> 5, :name => "tb_field_num"}
      @ceh[cname] = ce
      return ce
    when 'Float'
      ce = RubyCurses::CellEditor.new RubyCurses::Field.new nil, {"focusable"=>false, "visible"=>false, "display_length"=> 5, :name => "tb_field_flt"}
      @ceh[cname] = ce
      return ce
    when "Boolean" #'TrueClass', 'FalseClass'
      ce = RubyCurses::CellEditor.new(RubyCurses::CheckBox.new nil, {"display_length"=> 0})
      @ceh[cname] = ce
      return ce
    else
      $log.debug " get_default_cell_editor_for_class UNKNOWN #{cname}"
      ce = RubyCurses::CellEditor.new RubyCurses::Field.new nil, {"focusable"=>false, "visible"=>false, "display_length"=> 6, :name => "tb_field_unk"}
      @ceh[cname] = ce
      return ce
    end
  end
end

#get_default_cell_renderer_for_class(cname) ⇒ Object

this is vry temporary and will change as we begin to use models - i need to pick columns renderer



373
374
375
376
# File 'lib/rbcurse/rtable.rb', line 373

def get_default_cell_renderer_for_class cname
  @crh || prepare_renderers
  @crh[cname] || @crh['String']
end

#get_table_column_modelObject

@deprecated, avoid usage



218
219
220
221
# File 'lib/rbcurse/rtable.rb', line 218

def get_table_column_model
  $log.debug " DEPRECATED. Pls use table_column_model()"
  @table_column_model 
end

#get_value_at(row, col) ⇒ Object

— row and column methods of Table —# must not give wrong results when columns switched!



305
306
307
308
# File 'lib/rbcurse/rtable.rb', line 305

def get_value_at row, col
  model_index = @table_column_model.column(col).model_index
  @table_model.get_value_at row, model_index
end

#goto_bottomObject



713
714
715
716
717
718
# File 'lib/rbcurse/rtable.rb', line 713

def goto_bottom
  @oldrow = @current_index
  rc = row_count
  @current_index = rc -1
  bounds_check
end

#goto_topObject



719
720
721
722
723
# File 'lib/rbcurse/rtable.rb', line 719

def goto_top
  @oldrow = @current_index
  @current_index = 0
  bounds_check
end

#handle_key(ch) ⇒ Object

key handling make separate methods so callable programmatically



513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
# File 'lib/rbcurse/rtable.rb', line 513

def handle_key(ch)
  return :UNHANDLED if @table_model.nil?
  @current_index ||= 0
  @toprow ||= 0
  h = scrollatrow()
  rc = @table_model.row_count
  if @is_editing and (ch != 27 and ch != ?\C-c and ch != 13)
    $log.debug " sending ch #{ch} to cell editor"
    ret = @cell_editor.component.handle_key(ch)
    @repaint_required = true
    $log.debug "RET #{ret} got from to cell editor"
    #set_form_col if ret != :UNHANDLED # added 2010-01-30 20:17 CURSOR POS TABBEDPANE
    return if ret != :UNHANDLED
  end
  case ch
  when KEY_UP  # show previous value
    editing_stopped if @is_editing # 2009-01-16 16:06 
    previous_row
  when KEY_DOWN  # show previous value
    editing_stopped if @is_editing # 2009-01-16 16:06 
    next_row
  when 27, ?\C-c
    editing_canceled
  when KEY_ENTER, 10, 13
    # actually it should fall through to the else
    return :UNHANDLED unless @cell_editing_allowed
    toggle_cell_editing

  when @KEY_ROW_SELECTOR # ?\C-x #32
    #add_row_selection_interval @current_index, @current_index
    toggle_row_selection @current_index #, @current_index
    @repaint_required = true
  when ?\C-n.getbyte(0)
    editing_stopped if @is_editing # 2009-01-16 16:06 
    scroll_forward
  when ?\C-p.getbyte(0)
    editing_stopped if @is_editing # 2009-01-16 16:06 
    scroll_backward
  when @KEY_GOTO_TOP # removed 48 (0) from here so we can trap numbers
    # please note that C-[ gives 27, same as esc so will respond after ages
    editing_stopped if @is_editing # 2009-01-16 16:06 
    goto_top
  when @KEY_GOTO_BOTTOM
    editing_stopped if @is_editing # 2009-01-16 16:06 
    goto_bottom
  when @KEY_SCROLL_RIGHT
    editing_stopped if @is_editing # dts 2009-02-17 00:35 
    scroll_right
  when @KEY_SCROLL_LEFT
    editing_stopped if @is_editing # dts 2009-02-17 00:35 
    scroll_left
  when ?0.getbyte(0)..?9.getbyte(0)
    $multiplier *= 10 ; $multiplier += (ch-48)
    #$log.debug " setting mult to #{$multiplier} in list "
    return 0
  else
    # there could be a case of editing here too!
    ret = process_key ch, self
    $multiplier = 0 
    return :UNHANDLED if ret == :UNHANDLED
  end
  return 0 # added 2010-03-14 13:27 
end

#init_varsObject



82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
# File 'lib/rbcurse/rtable.rb', line 82

def init_vars
  @col_offset = @row_offset = 1
  @focusable= true
  @current_index = 0
  @current_column = 0
  @oldrow = @oldcol = 0
  @current_column_offset ||= 0 # added 2009-01-12 19:06 current_column's offset
  @toprow = 0
  @to_print_borders ||= 1
  @show_grid ||= 1
  @_first_column_print = 0 # intro for horiz scrolling 2009-02-14 16:20 
  @_last_column_print = 0 # 2009-02-16 23:57 so we don't tab further etc. 
  # table needs to know what columns are being printed.
  @curpos = 0
  @inter_column_spacing = 1
  # @selected_color ||= 'yellow'
  # @selected_bgcolor ||= 'black'
  @table_changed = true
  @repaint_required = true
end

#install_keys_bindingsObject



102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
# File 'lib/rbcurse/rtable.rb', line 102

def install_keys_bindings

  # alt-tab next column
  # alt-shift-tab prev column
  #bind_key(?\M-\C-i) { next_column }
  #bind_key(481) { previous_column }
  bind_key(9) { next_column }
  bind_key(353) { previous_column }
  bind_key(KEY_RIGHT) { next_column }
  bind_key(KEY_LEFT) { previous_column }
  bind_key(@KEY_ASK_FIND_FORWARD) { ask_search_forward }
  bind_key(@KEY_ASK_FIND_BACKWARD) { ask_search_backward }
  bind_key(@KEY_FIND_NEXT) { find_next }
  bind_key(@KEY_FIND_PREV) { find_prev }
  # added 2010-05-12 21:41 for vim keys, will work if cell editing allowed is false
  # user should be able to switch to editable and off so he can use keys TODO
  # TODO vim_editable mode: C dd etc . to repeat change, how about range commands like vim
  # TODO use numeric to widen, so we can distribute spacing
  bind_key(?j){ next_row() }
  bind_key(?k){ previous_row() }
  bind_key(?G){ goto_bottom() }
  bind_key([?g,?g]){ goto_top() }
  bind_key(?l) { next_column }
  bind_key(?h) { previous_column }
end

#is_cell_selected(row, col) ⇒ Object



234
235
236
# File 'lib/rbcurse/rtable.rb', line 234

def is_cell_selected row, col
  raise "TODO "
end

#is_column_selected(col) ⇒ Object

— selection methods —#



231
232
233
# File 'lib/rbcurse/rtable.rb', line 231

def is_column_selected col
  raise "TODO "
end

#move_column(ix, newix) ⇒ Object



298
299
300
301
# File 'lib/rbcurse/rtable.rb', line 298

def move_column ix, newix
  @table_column_model.move_column ix, newix
  #table_structure_changed # this should be called by tcm TODO with object
end

#next_column(num = (($multiplier.nil? or $multiplier == 0) ? 1 : $multiplier)) ⇒ Object

move focus to next column

2009-10-07 12:47 behavior change. earlier this would move to next row
if focus was on last visible field. Now it scrolls so that first invisible
field becomes the first column. 
# 2010-05-13 12:42 added multiplier

def next_column



655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
# File 'lib/rbcurse/rtable.rb', line 655

def next_column num=(($multiplier.nil? or $multiplier == 0) ? 1 : $multiplier)
  $multiplier = 0 # so not used again in next row
  #v =  @current_column+1 
  v =  @current_column + num
  # normal situation, there is a next column go to
  if v < @table_column_model.column_count 
    if v <= @_last_column_print
      $log.debug " if v < #{@table_column_model.column_count} nd lastcolprint "
      current_column v
    else
      # there is a col but its not visible
      # XXX inefficient but i scroll completely to next column (putting it at start)
      # otherwise sometimes it was still not visible if last column
      (v-@_first_column_print).times(){scroll_right}
      current_column v
      set_form_col 
    end

  else
    if @current_index < row_count()-1 
      $log.debug " GOING TO NEXT ROW FROM NEXT COL : #{@current_index} : #{row_count}"
      @current_column = 0
      #@current_column = @_first_column_print # added 2009-02-17 00:01 
      @_first_column_print = 0 # added 2009-10-07 11:25 
      next_row 1
      set_form_col
      @repaint_required = true
      @table_changed = true    # so columns are modified by print_header
    else
      return :UNHANDLED
    end
  end
end

#next_row(num = (($multiplier.nil? or $multiplier == 0) ? 1 : $multiplier)) ⇒ Object

def next_row goto next row added multipler 2010-05-12 20:51



638
639
640
641
642
643
644
645
646
647
648
# File 'lib/rbcurse/rtable.rb', line 638

def next_row num=(($multiplier.nil? or $multiplier == 0) ? 1 : $multiplier)
  rc = row_count
  @oldrow = @current_index
  # don't go on if rc 2009-01-16 19:55  XXX
  if @current_index < rc
    #@current_index += 1 
    @current_index += 1*num if @current_index < rc
    bounds_check
  end
  $multiplier = 0
end

#on_enterObject

on enter of widget the cursor should be appropriately positioned



811
812
813
814
815
816
# File 'lib/rbcurse/rtable.rb', line 811

def on_enter
  super
  set_form_row
  set_form_col # 2009-01-17 01:35 
  on_enter_cell focussed_row(), focussed_col() unless focussed_row().nil? or focussed_col().nil?
end

#on_enter_cell(arow, acol) ⇒ Object

OECE



797
798
799
800
801
802
803
804
805
806
807
808
# File 'lib/rbcurse/rtable.rb', line 797

def on_enter_cell arow, acol
  $log.debug " def on_enter_cell #{arow}, #{acol}"
  if @table_traversal_event.nil? 
    @table_traversal_event ||= TableTraversalEvent.new @oldrow, @oldcol, arow, acol, self
  else
    @table_traversal_event.set(@oldrow, @oldcol, arow, acol, self)
  end
  fire_handler :TABLE_TRAVERSAL_EVENT, @table_traversal_event
  if @editing_policy == :EDITING_AUTO
    editing_started
  end
end

#on_enter_column(acol) ⇒ Object



784
785
786
787
# File 'lib/rbcurse/rtable.rb', line 784

def on_enter_column acol
  #$log.debug " def on_enter_column #{acol}"
  on_enter_cell @current_index, acol
end

#on_enter_row(arow) ⇒ Object



780
781
782
783
# File 'lib/rbcurse/rtable.rb', line 780

def on_enter_row arow
  #$log.debug " def on_enter_row #{arow}"
  on_enter_cell arow, @current_column
end

#on_leaveObject



817
818
819
820
821
# File 'lib/rbcurse/rtable.rb', line 817

def on_leave
  super
  $log.debug " on leave of table 2009-01-16 21:58 "
  editing_stopped if @is_editing #  2009-01-16 21:58 
end

#on_leave_cell(arow, acol) ⇒ Object

OLCE



789
790
791
792
793
794
795
# File 'lib/rbcurse/rtable.rb', line 789

def on_leave_cell arow, acol
  $log.debug " def on_leave_cell #{arow}, #{acol}"
  #if @editing_policy == :EDITING_AUTO  # actually this should happen in all cases
  if @is_editing # 2009-01-17 00:49 
    editing_stopped arow, acol
  end
end

#on_leave_column(acol) ⇒ Object



775
776
777
778
779
# File 'lib/rbcurse/rtable.rb', line 775

def on_leave_column acol
  #$log.debug " def on_leave_column #{acol}"
  #on_leave_cell @current_index, acol
  on_leave_cell @oldrow, acol
end

#on_leave_row(arow) ⇒ Object



770
771
772
773
774
# File 'lib/rbcurse/rtable.rb', line 770

def on_leave_row arow
  #$log.debug " def on_leave_row #{arow}"
  #on_leave_cell arow, @current_column
  on_leave_cell arow, @oldcol # 2009-01-16 19:41 XXX trying outt
end

#prepare_editor(editor, row, col, value) ⇒ Object



438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
# File 'lib/rbcurse/rtable.rb', line 438

def prepare_editor editor, row, col, value
  r,c = rowcol
  row = r + (row - @toprow) +1  #  @form.row , 1 added for header row!
  col = c+get_column_offset()
  editor.prepare_editor self, row, col, value
  # added on 2009-02-16 23:49 
  # if data is longer than can be displayed then update editors disp len too
  if (col+editor.component.display_length)>= @col+@width
    editor.component.display_length = @width-1-col
    $log.debug "DDDXXX #{editor.component.display_length} = @width-1-col"
  else
  $log.debug "EEE if (#{col+editor.component.display_length})> #{@col+@width}"
  end
  @cell_editor = editor
  @repaint_required = true
  # copied from rlistbox, so that editors write on parent's graphic, otherwise
  # their screen updates get overwritten by parent. 2010-01-19 20:17 
  if @should_create_buffer
    $log.debug "LB #{@name} overriding editors comp with GRAPHIC #{@graphic} "
    editor.component.override_graphic(@graphic) #  2010-01-05 00:36 TRYING OUT BUFFERED
  end
  set_form_col 
end

#prepare_renderersObject

to do for TrueClass and FalseClass



359
360
361
362
363
364
365
366
367
368
369
370
# File 'lib/rbcurse/rtable.rb', line 359

def prepare_renderers
  @crh = Hash.new
  @crh['String'] = TableCellRenderer.new "", {"parent" => self }
  @crh['Fixnum'] = TableCellRenderer.new "", { "justify" => :right, "parent" => self}
  @crh['Float'] = TableCellRenderer.new "", {"justify" => :right, "parent" => self}
  @crh['TrueClass'] = CheckBoxCellRenderer.new "", {"parent" => self, "display_length"=>7}
  @crh['FalseClass'] = CheckBoxCellRenderer.new "", {"parent" => self, "display_length"=>7}
  @crh['Time'] = TableDateCellRenderer.new "", {"parent" => self, "display_length"=>16}
  #@crh['String'] = TableCellRenderer.new "", {"bgcolor" => "cyan", "color"=>"white", "parent" => self}
  #@crh['Fixnum'] = TableCellRenderer.new "", {"display_length" => 6, "justify" => :right, "color"=>"blue","bgcolor"=>"cyan" }
  #@crh['Float'] = TableCellRenderer.new "", {"display_length" => 6, "justify" => :right, "color"=>"blue", "bgcolor"=>"cyan" }
end

#previous_column(num = (($multiplier.nil? or $multiplier == 0) ? 1 : $multiplier)) ⇒ Object

move focus to previous column if you are on first column, check if scrolling required, else move up to last visible column of prev row def previous_column



692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
# File 'lib/rbcurse/rtable.rb', line 692

def previous_column num=(($multiplier.nil? or $multiplier == 0) ? 1 : $multiplier)
  v =  @current_column - num # 2010-05-13 12:44 1 to num
  # returning unhandled so focus can go to prev field auto
  if v < @_first_column_print and @current_index <= 0
    return :UNHANDLED
  end
  if v < @_first_column_print
    if v > 0
      scroll_left
      current_column v
    elsif @current_index >  0
      @current_column = @table_column_model.column_count-1
      @current_column = @_last_column_print # added 2009-02-17 00:01 
      $log.debug " XXXXXX prev col #{@current_column}, las #{@_last_column_print}, fi: #{@_first_column_print}"
      set_form_col
      previous_row 1
    end
  else
    current_column v
  end
end

#previous_row(num = (($multiplier.nil? or $multiplier == 0) ? 1 : $multiplier)) ⇒ Object

def previous_row



626
627
628
629
630
631
632
633
634
# File 'lib/rbcurse/rtable.rb', line 626

def previous_row num=(($multiplier.nil? or $multiplier == 0) ? 1 : $multiplier)
  @oldrow = @current_index
#  @current_index -= 1 if @current_index > 0
  num.times { 
    @current_index -= 1 if @current_index > 0
  }
  $multiplier = 0
  bounds_check
end


971
972
973
974
975
976
977
978
# File 'lib/rbcurse/rtable.rb', line 971

def print_border g
  return unless @table_changed
  g.print_border @row, @col, @height-1, @width, $datacolor
  return if @table_model.nil?
  rc = @table_model.row_count
  h = scrollatrow()
  _print_more_data_marker (rc>h)
end


993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
# File 'lib/rbcurse/rtable.rb', line 993

def print_header
  return unless @table_changed
      $log.debug " TABLE: inside printheader 2009-10-07 11:51  DDD "

  r,c = rowcol
  header_model = @table_header.table_column_model
  tcm = @table_column_model ## could have been overridden, should we use this at all
  offset = 0
  header_model.each_with_index do |tc, colix|
    next if colix < @_first_column_print # added for scrolling rt and left 2009-02-14 17:49 
    acolumn = tcm.column colix
    renderer = tc.cell_renderer
    renderer = @table_header.default_renderer if renderer.nil?
    renderer.display_length acolumn.width unless acolumn.nil?
    width = renderer.display_length + 1
    content = tc.header_value
    if c+offset+width > @col+@width
      #$log.debug " TABLE: experimental code to NOT print if chance of exceeding table width"
      # 2009-02-14 14:24 now printing, but truncating data for last column
          space_left = (@width-3)-(offset)
          space_left = 0 if space_left < 0
          if content.length > space_left
            clen = space_left
            renderer.display_length clen
          else
            clen = -1
            renderer.display_length space_left
          end
          #$log.debug " TABLE BREAKING SINCE sl: #{space_left},#{crow},#{colix}: #{clen} "
    # passing self so can prevent renderer from printing outside 2009-10-05 22:56 
          #renderer.repaint @graphic, r, c+(offset), 0, content[0..clen], false, false
          renderer.repaint self, r, c+(offset), 0, content[0..clen], false, false
      break
    end
    # passing self so can prevent renderer from printing outside 2009-10-05 22:56 
    #renderer.repaint @graphic, r, c+(offset),0, content, false, false
    renderer.repaint self, r, c+(offset),0, content, false, false
    offset += width
  end
end

#printstring(r, c, string, color, att) ⇒ Object

NEW to correct overflow

2009-10-05 21:34 
when resizing columns a renderer can go outside the table bounds
so printing should be done by parent not window


957
958
959
960
961
962
963
964
965
966
967
968
969
970
# File 'lib/rbcurse/rtable.rb', line 957

def printstring(r,c,string, color, att)
  # 3 is table borders
  # if renderer trying to print outside don't let it
  if c > @col+@width-3
    return
  end
  # if date exceeds boundary truncate
  if c+string.length > (@col+@width)-3
    len = string.length-((c+string.length)-(@col+@width-3))
    @graphic.printstring(r,c,string[0..len], color,att)
  else
    @graphic.printstring(r,c,string, color,att)
  end
end

#remove_column(tc) ⇒ Object

table_structure_changed # this should be called by tcm TODO with object



282
283
284
285
# File 'lib/rbcurse/rtable.rb', line 282

def remove_column tc
  @table_column_model.remove_column  tc
  #table_structure_changed # this should be called by tcm TODO with object
end

#remove_column_selection_interval(ix0, ix1) ⇒ Object

if column_selection_allowed



241
242
243
# File 'lib/rbcurse/rtable.rb', line 241

def remove_column_selection_interval ix0, ix1
  raise "TODO "
end

#repaintObject



850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
# File 'lib/rbcurse/rtable.rb', line 850

def repaint
  safe_create_buffer # moved here 2010-02-19 09:53 RFED16
  return unless @repaint_required
  my_win = @form ? @form.window : @target_window
  @graphic = my_win unless @graphic
  #$log.warn "neither form not target window given!!! TV paint 368" unless my_win
  raise " #{@name} neither form, nor target window given TV paint " unless my_win
  raise " #{@name} NO GRAPHIC set as yet                 TV paint " unless @graphic
  @win_left = my_win.left # unused remove TODO
  @win_top = my_win.top

  print_border @graphic if @to_print_borders == 1 # do this once only, unless everything changes
  return if @table_model.nil? # added 2009-02-17 12:45 
  @_first_column_print ||= 0
  cc = @table_model.column_count
  rc = @table_model.row_count
  inter_column_padding = " " * @inter_column_spacing 
  @_last_column_print = cc-1
  tcm = @table_column_model
  tm = @table_model
  tr = @toprow
  _column_scrolling = false
  acolor = get_color $datacolor
  h = scrollatrow()
  r,c = rowcol
  # each cell should print itself, however there is a width issue. 
  # Then thee
  print_header # do this once, unless columns changed
  # TCM should give modelindex of col which is used to fetch data from TM
  r += 1 # save for header
  0.upto(h) do |hh|
    crow = tr+hh  # crow is the row
    if crow < rc
      offset = 0 # offset of column
#      0.upto(cc-1) do |colix|
      focussed = @current_index == crow ? true : false 
      selected = is_row_selected crow
      # we loop through column_model and fetch data based on model index
      # FIXED better to call table.get_value_at since we may now 
      # introduce a view - 2009-01-18 18:21 
      tcm.each_with_index do |acolumn, colix|
        next if colix < @_first_column_print
        #acolumn = tcm.column(colix)
        #model_index = acolumn.model_index
        content = get_value_at(crow, colix)  # tables
        renderer = get_cell_renderer(crow, colix)
        if renderer.nil?
          renderer = get_default_cell_renderer_for_class(content.class.to_s) if renderer.nil?
          renderer.display_length acolumn.width unless acolumn.nil?
        end
        width = renderer.display_length + @inter_column_spacing
        acolumn.column_offset = offset
        # trying to ensure that no overprinting
        if c+offset+width > @col+@width
          _column_scrolling = true
          @_last_column_print = colix
          # experimental to print subset of last
          space_left = (@width-3)-(offset) # 3 due to boundaries
          space_left = 0 if space_left < 0
          # length bombed for trueclass 2009-10-05 19:34 
          contentlen = content.length rescue content.to_s.length
          #if content.length > space_left
          if contentlen > space_left
            clen = space_left
            renderer.display_length clen
          else
            clen = -1
            renderer.display_length space_left # content.length
          end
          # added 2009-10-05 20:29 since non strings were bombing
          # in other cases should be just pass the content as-is. XXX
          contenttrim = content[0..clen] rescue content # .to_s[0..clen]
          # print the inter cell padding just in case things mess up while scrolling
          @graphic.mvprintw r+hh, c+offset-@inter_column_spacing, inter_column_padding
          #renderer.repaint @graphic, r+hh, c+offset, crow, content[0..clen], focussed, selected
          #renderer.repaint @graphic, r+hh, c+offset, crow, contenttrim, focussed, selected
          # 2009-10-05 20:35 XXX passing self so we check it doesn't print outside
          renderer.repaint self, r+hh, c+offset, crow, contenttrim, focussed, selected
          break
        end
        # added crow on 2009-02-11 22:46 
        #renderer.repaint @graphic, r+hh, c+(offset), crow, content, focussed, selected
          # 2009-10-05 20:35 XXX
        renderer.repaint self, r+hh, c+(offset), crow, content, focussed, selected
        offset += width
      end
    else
      #@graphic.printstring r+hh, c, " " * (@width-2), acolor,@attr
      printstring r+hh, c, " " * (@width-2), acolor,@attr
      # clear rows
    end
  end
  if @is_editing
    @cell_editor.component.repaint unless @cell_editor.nil? or @cell_editor.component.form.nil?
  end
  _print_more_columns_marker _column_scrolling
  _print_more_data_marker(rc-1 > tr + h)
  $log.debug " _print_more_data_marker(#{rc} >= #{tr} + #{h})"
  @table_changed = false
  @repaint_required = false
  @buffer_modified = true
  buffer_to_window # RFED16 2010-02-19 09:55 
end

#row_countObject

added 2009-01-07 13:05 so new scrollable can use



139
140
141
142
# File 'lib/rbcurse/rtable.rb', line 139

def row_count
  return 0 if @table_model.nil?
  @table_model.row_count
end

#scroll_backwardObject



724
725
726
727
728
729
# File 'lib/rbcurse/rtable.rb', line 724

def scroll_backward
  @oldrow = @current_index
  h = scrollatrow()
  @current_index -= h 
  bounds_check
end

#scroll_forwardObject



730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
# File 'lib/rbcurse/rtable.rb', line 730

def scroll_forward
  @oldrow = @current_index
  h = scrollatrow()
  rc = row_count
  # more rows than box
  if h < rc
    @toprow += h+1 #if @current_index+h < rc
    @current_index = @toprow
  else
    # fewer rows than box
    @current_index = rc -1
  end
  #@current_index += h+1 #if @current_index+h < rc
  bounds_check
end

#scroll_leftObject



1089
1090
1091
1092
1093
1094
1095
1096
1097
# File 'lib/rbcurse/rtable.rb', line 1089

def scroll_left
  if @_first_column_print > 0
    @_first_column_print -= 1
    @current_column =  @_first_column_print
      set_form_col
    @repaint_required = true
    @table_changed = true
  end
end

#scroll_rightObject



1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
# File 'lib/rbcurse/rtable.rb', line 1078

def scroll_right
  cc = @table_model.column_count
  if @_first_column_print < cc-1
    @_first_column_print += 1
    @_last_column_print += 1 if @_last_column_print < cc-1
    @current_column =  @_first_column_print
      set_form_col # FIXME not looking too good till key press
    @repaint_required = true
    @table_changed = true    # so columns are modified
  end
end

#scrollatrowObject

added 2009-01-07 13:05 so new scrollable can use



144
145
146
147
# File 'lib/rbcurse/rtable.rb', line 144

def scrollatrow
  #@height -3
  @height -4 # we forgot to remove 1 from height in border.
end

#selected_columnObject



245
246
247
# File 'lib/rbcurse/rtable.rb', line 245

def selected_column
  @table_column_model.selected_columns[0]
end

#selected_column_countObject



251
252
253
# File 'lib/rbcurse/rtable.rb', line 251

def selected_column_count
  @table_column_model.selected_column_count
end

#selected_columnsObject



248
249
250
# File 'lib/rbcurse/rtable.rb', line 248

def selected_columns
  @table_column_model.selected_columns
end

#set_column_widths(cw) ⇒ Object

convenience method sets column widths given an array of ints You may get such an array from estimate_column_widths



1166
1167
1168
1169
1170
1171
1172
# File 'lib/rbcurse/rtable.rb', line 1166

def set_column_widths cw
  tcm = @table_column_model
  tcm.each_with_index do |col, ix|
    col.width cw[ix]
  end
  table_structure_changed(nil)
end

#set_data(data, colnames_array) ⇒ Object

Sets the data in models Should replace if these are created. TODO FIXME



152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
# File 'lib/rbcurse/rtable.rb', line 152

def set_data data, colnames_array
  # next 2 added in case set_data called again
  @table_changed = true
  @repaint_required = true
  if data.is_a? Array
    model = RubyCurses::DefaultTableModel.new data, colnames_array
    table_model model
  elsif data.is_a? RubyCurses::TableModel
    table_model data
  else
    raise "set_data: don't know how to handle data: #{data.class.to_s}"
  end
  if colnames_array.is_a? Array
    model = DefaultTableColumnModel.new colnames_array
    table_column_model model
  elsif colnames_array.is_a? RubyCurses::TableColumnModel
    table_column_model  colnames_array
  else
    raise "set_data: don't know how to handle column data: #{colnames_array.class.to_s}"
  end
  create_default_list_selection_model
  create_table_header
end

#set_default_cell_renderer_for_class(cname, rend) ⇒ Object



377
378
379
380
# File 'lib/rbcurse/rtable.rb', line 377

def set_default_cell_renderer_for_class cname, rend
  @crh ||= {}
  @crh[cname]=rend
end

#set_focus_on(arow) ⇒ Object

2009-01-17 13:25



1034
1035
1036
1037
1038
# File 'lib/rbcurse/rtable.rb', line 1034

def set_focus_on arow
  @oldrow = @current_index
  @current_index = arow
  bounds_check if @oldrow != @current_index  
end

#set_form_col(col = @curpos) ⇒ Object

set cursor on correct column, widget



833
834
835
836
837
838
839
840
841
842
# File 'lib/rbcurse/rtable.rb', line 833

def set_form_col col=@curpos
  @curpos = col
  @cols_panned ||= 0 # RFED16 2010-02-19 10:00 
  @current_column_offset = get_column_offset 
  #@form.col = @col + @col_offset + @curpos + @current_column_offset
  #[email protected]
  win_col = 0 # RFED16 2010-02-19 10:00 
  fcol = @col + @col_offset + @curpos + @current_column_offset + @cols_panned + win_col
  setrowcol(nil, fcol) # 2010-01-18 20:04 
end

#set_form_rowObject



822
823
824
825
826
827
828
829
830
831
# File 'lib/rbcurse/rtable.rb', line 822

def set_form_row
  r,c = rowcol
  @rows_panned ||= 0 # RFED16 2010-02-19 10:00 
  win_row = 0
  #[email protected] # 2010-01-18 20:28 added
  # +1 is due to header
  #@form.row = r + (@current_index-@toprow) + 1
  frow = r + (@current_index-@toprow) + 1 + win_row + @rows_panned
  setrowcol(frow, nil) # 2010-01-18 20:04 
end

#set_model(tm, tcm = nil, lsm = nil) ⇒ Object



175
176
177
178
179
180
181
182
183
184
185
186
187
188
# File 'lib/rbcurse/rtable.rb', line 175

def set_model tm, tcm=nil, lsm=nil
  table_model tm
  if tcm.nil?
    create_default_table_column_model
  else
    table_column_model tcm
  end
  if lsm.nil?
    create_default_list_selection_model
  else
    list_selection_model lsm
  end
  create_table_header
end

#set_value_at(row, col, value) ⇒ Object

must not give wrong results when columns switched!



310
311
312
313
# File 'lib/rbcurse/rtable.rb', line 310

def set_value_at row, col, value
  model_index = @table_column_model.column(col).model_index
  @table_model.set_value_at row, model_index, value
end

#size_columns_to_fitObject



1173
1174
1175
1176
1177
1178
1179
1180
# File 'lib/rbcurse/rtable.rb', line 1173

def size_columns_to_fit
  delta = @width - table_column_model().get_total_column_width()
  tcw = table_column_model().get_total_column_width()

  $log.debug "size_columns_to_fit D #{delta}, W #{@width}, TCW #{tcw}"
  accomodate_delta(delta) if delta != 0
  #set_width_from_preferred_widths
end

#table_column_model(*val) ⇒ Object

updated this so no param will return the tcm 2009-02-14 12:31



202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
# File 'lib/rbcurse/rtable.rb', line 202

def table_column_model(*val)
  if val.empty?
    return @table_column_model
  end
  tcm = val[0]
  raise "data error: table_column_model wrong class" if !tcm.is_a? RubyCurses::TableColumnModel
  @table_column_model = tcm
  @table_column_model.bind(:TABLE_COLUMN_MODEL_EVENT) {|e| 
    table_structure_changed e
  }
  @table_column_model.bind(:PROPERTY_CHANGE){|e| column_property_changed(e)}

  #@table_header.column_model(tcm) unless @table_header.nil?
  @table_header.table_column_model=(tcm) unless @table_header.nil?
end

#table_data_changed(tabmodev) ⇒ Object

— event listener support methods (p521) TODO —#



317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
# File 'lib/rbcurse/rtable.rb', line 317

def table_data_changed tabmodev
  #$log.debug " def table_data_changed got #{tabmodev}"
  @repaint_required = true
  # next was required otherwise on_enter would bomb if data changed from outside
  if row_count == 0
    init_vars
    set_form_col # added 2009-01-24 14:32 since cursor was still showing on existing col
    return #  added 2009-01-23 15:15 
  end
  # the next block to be only called if user is inside editing. Often data will be refreshed by
  # a search field and this gets called.
  if @is_editing
    @is_editing = false # 2009-01-19 18:18 testing this out XXX
    # we need to refresh the editor if you deleted a row while sitting on it
    # otherwise it shows the old value
    editing_started 
  end
end

#table_model(*val) ⇒ Object

getter and setter for table_model



191
192
193
194
195
196
197
198
199
200
# File 'lib/rbcurse/rtable.rb', line 191

def table_model(*val)
  if val.empty?
    @table_model
  else
    raise "data error" if !val[0].is_a? RubyCurses::TableModel
    @table_model = val[0] 
    ## table registers as a listener, or rather binds to event
    @table_model.bind(:TABLE_MODEL_EVENT){|lde| table_data_changed(lde) }
  end
end

#table_structure_changed(tablecolmodelevent) ⇒ Object



335
336
337
338
339
340
# File 'lib/rbcurse/rtable.rb', line 335

def table_structure_changed tablecolmodelevent
  $log.debug " def table_structure_changed #{tablecolmodelevent}"
  @table_changed = true
  @repaint_required = true
  init_vars
end

#toggle_cell_editingObject



581
582
583
584
585
586
587
588
589
# File 'lib/rbcurse/rtable.rb', line 581

def toggle_cell_editing
  return unless @cell_editing_allowed
  @is_editing = !@is_editing
  if @is_editing 
    editing_started
  else
    editing_stopped
  end
end