class Canis::TabularWidget

A viewable read only, scrollable table. This is supposed to be a minimal, and (hopefully) fast version of Table (@see rtable.rb).

Attributes

_header_adjustment[R]
columns[R]

@endgroup select related

current_index[RW]

dsl_accessor :suppress_borders

numbering[RW]

boolean, whether lines should be numbered

selected_index[RW]
selected_indices[R]

index of selected rows, if multiple selection asked for

table_row_sorter[R]

default or custom sorter

toprow[R]

Public Class Methods

new(form = nil, config={}) click to toggle source
Calls superclass method
# File lib/canis/core/widgets/deprecated/tabularwidget.rb, line 91
def initialize form = nil, config={}, &block
  @focusable = true
  @editable = false
  @sanitization_required = true
  @estimate_column_widths = true
  @row = 0
  @col = 0
  @cw = {} # column widths keyed on column index - why not array ??
  @pw = [] # preferred column widths 2010-10-20 12:58
  @calign = {} # columns aligns values, on column index
  @coffsets = {}
  @suppress_borders = false
  @row_offset = @col_offset = 1 
  @chash = {}
  # this should have index of displayed column
  # so user can reorder columns
  #@column_position = [] # TODO
  @separ = @columns = @numbering =  nil
  @y = '|'
  @x = '+'
  @list = []
  @_header_adjustment = 0
  @show_focus = false  # don't highlight row under focus TODO
  @selection_mode = :multiple # default is multiple, anything else given becomes single
  @row_selected_symbol = '*'
  @show_selector = true
  super
  # ideally this should have been 2 to take care of borders, but that would break
  # too much stuff !
  @win = @graphic

  @_events.push :CHANGE # thru vieditable
  @_events << :PRESS # new, in case we want to use this for lists and allow ENTER
  @_events << :ENTER_ROW # new, should be there in listscrollable ??
  @_events << :COLUMN_RESIZE_EVENT 
  install_keys # << almost jnuk now, clean off TODO
  init_vars
  map_keys
  bordertitle_init
end

Public Instance Methods

<<(array)
Alias for: add
[](off0) click to toggle source
# File lib/canis/core/widgets/deprecated/tabularwidget.rb, line 231
def [](off0)
  @list[off0]
end
[]=(off0, data) click to toggle source
# File lib/canis/core/widgets/deprecated/tabularwidget.rb, line 227
def []=(off0, data)
  @repaint_required = true
  @list[off0] = data
end
add(array) click to toggle source

add a row of data

NOTE: this is not creating a table sorter

@param [Array] an array containing entries for each column

# File lib/canis/core/widgets/deprecated/tabularwidget.rb, line 205
def add array
  @list ||= []
  @list << array
  @repaint_required = true
  @recalc_required = true
end
Also aliased as: <<, add_row, append
add_row(array)
Alias for: add
append(array)
Alias for: add
calculate_column_width(col) click to toggle source

if user has not specified preferred_width for a column then we can calculate the same based on data

# File lib/canis/core/widgets/deprecated/tabularwidget.rb, line 823
def calculate_column_width col
  ret = @cw[col] || 2
  ctr = 0
  @list.each_with_index { |r, i| 
    #next if i < @toprow # this is also a possibility, it checks visible rows
    break if ctr > 10
    ctr += 1
    next if r == :separator
    c = r[col]
    x = c.to_s.length
    ret = x if x > ret
  }
  ret
end
column_align(colindex, lrc) click to toggle source

set alignment of given column offset @param [Number] column offset, starting 0 @param [Symbol] :left, :right

# File lib/canis/core/widgets/deprecated/tabularwidget.rb, line 297
def column_align colindex, lrc
  raise ArgumentError, "wrong alignment value sent" if ![:right, :left, :center].include? lrc
  @calign[colindex] = lrc
  get_column(colindex).align = lrc
  @repaint_required = true
  #@recalc_required = true
end
column_hidden(colindex, tf=true) click to toggle source

Set a column to hidden TODO we are not actually doing that

# File lib/canis/core/widgets/deprecated/tabularwidget.rb, line 305
def column_hidden colindex, tf=true
  #raise ArgumentError, "wrong alignment value sent" if ![:right, :left, :center].include? lrc
  get_column(colindex).hidden = tf
  @repaint_required = true
  @recalc_required = true
end
column_width(colindex, width) click to toggle source

TODO more methods like in listbox so interchangeable, delete_at etc

# File lib/canis/core/widgets/deprecated/tabularwidget.rb, line 284
def column_width colindex, width
  return if width < 0
  raise ArgumentError, "wrong width value sent: #{width} " if width.nil? || !width.is_a?(Fixnum) || width < 0
  @cw[colindex] = width # uncommented 2011-12-1 for expand on +
  @pw[colindex] = width # XXXXX
  get_column(colindex).width = width
  @repaint_required = true
  @recalc_required = true
end
columns=(array) click to toggle source

set column names @param [Array] column names or headings

# File lib/canis/core/widgets/deprecated/tabularwidget.rb, line 160
def columns=(array)
  @_header_adjustment = 1
  @columns = array
  @columns.each_with_index { |c,i| 
    @cw[i] ||= c.to_s.length
    @calign[i] ||= :left
  }
  # maintains index in current pointer and gives next or prev
  @column_pointer = Circular.new @columns.size()-1
end
Also aliased as: headings=
contract_column() click to toggle source
# File lib/canis/core/widgets/deprecated/tabularwidget.rb, line 320
def contract_column
  x = _convert_curpos_to_column
  w = get_column(x).width || @cw[x]
  column_width x, w-1 if w
end
convert_value_to_text(r, count) click to toggle source

convert data object to a formatted string for print NOTE: useful for overriding and doing custom formatting @param [Array] array of column data, mostly String

Can also be :columns or :separator

@param [Fixnum] index of row in data

# File lib/canis/core/widgets/deprecated/tabularwidget.rb, line 735
def convert_value_to_text r, count
  if r == :separator
    return separator
  elsif r == :columns
    return "??" unless @columns # column was requested but not supplied
    # FIXME putting entire header into this, take care of hidden
    r = []
    @columns.each_with_index { |e, i| r << e unless get_column(i).hidden  }
    return @headerfmtstr % r if @numbering
  end
  str = ""

  if @numbering
    #r = r.dup
    #r.insert 0, count+1
    # TODO get the width
    str << "%*d |"%  [2, count + 1]
  end
  # unroll r, get width and align
  # This is to truncate column to requested width
  fmta = []
  r.each_with_index { |e, i| 
    next if get_column(i).hidden == true
    #w = @pw[i] || @cw[i]  # XXX
    #$log.debug "WIDTH XXX  #{i} w= #{w} , #{@pw[i]}, #{@cw[i]} :: #{e} " if $log.debug?
    w = @cw[i]
    l = e.to_s.length
    fmt = "%-#{w}s "
    # if value is longer than width, then truncate it
    if l > w
      fmt = "%.#{w}s "
    else
      # ack we don;t need to recalc this we can pull out of hash FIXME
      case @calign[i]
      when :right
        fmt = "%#{w}s "
      else
        fmt = "%-#{w}s "
      end
    end
    str << fmt % e
    fmta << fmt
  }
  #fmstr = fmta.join(@y)
  #return fmstr % r; # FIXME hidden column still goes int
  return str
end
create_default_sorter() click to toggle source
# File lib/canis/core/widgets/deprecated/tabularwidget.rb, line 214
def create_default_sorter
  raise "Data not sent in." unless @list
  @table_row_sorter = TableRowSorter.new @list
end
current_value() click to toggle source

returns value of current row. NOTE: you may need to adjust it with _header_adjustment - actually you can't this may give wrong row – depends what you want.

# File lib/canis/core/widgets/deprecated/tabularwidget.rb, line 423
def current_value
  @list[@current_index-@_header_adjustment] # XXX added header_adju 2010-11-01 11:14
end
data=(data) click to toggle source
# File lib/canis/core/widgets/deprecated/tabularwidget.rb, line 198
def data=(data)
  set_content(data, nil)
end
delete_at(off0) click to toggle source
# File lib/canis/core/widgets/deprecated/tabularwidget.rb, line 222
def delete_at off0
  @repaint_required = true
  @delete_buffer=@list.delete_at off0
  return @delete_buffer
end
delete_line(line=real_index()) click to toggle source

delete current line or lines Should be using listeditable except for _header_adjustment NOTE: user has to map this to some key such as 'dd'

tw.bind_key([?\d,?\d]) { tw.delete_line }
# File lib/canis/core/widgets/deprecated/tabularwidget.rb, line 244
def delete_line line=real_index()
  #return -1 unless @editable
  if !$multiplier || $multiplier == 0 
    @delete_buffer = @list.delete_at line
  else
    @delete_buffer = @list.slice!(line, $multiplier)
  end
  @curpos ||= 0 # rlist has no such var
  $multiplier = 0
  #add_to_kill_ring @delete_buffer
  @buffer = @list[@current_index]
  if @buffer.nil?
    up
    setrowcol @row + 1, nil # @form.col
  end
  # warning: delete buffer can now be an array
  #fire_handler :CHANGE, InputDataEvent.new(@curpos,@curpos+@delete_buffer.length, self, :DELETE_LINE, line, @delete_buffer)     #  2008-12-24 18:34
  set_modified 
  #@widget_scrolled = true
  @repaint_required = true
end
expand_column() click to toggle source
# File lib/canis/core/widgets/deprecated/tabularwidget.rb, line 314
def expand_column
  x = _convert_curpos_to_column
  w = get_column(x).width || @cw[x]
  # sadly it seems to be nil
  column_width x, w+1 if w
end
fire_action_event() click to toggle source

on pressing ENTER we send user some info, the calling program would bind :PRESS Added a call to sort, should i still call PRESS or just do a sort in here and not call PRESS ???

# File lib/canis/core/widgets/deprecated/tabularwidget.rb, line 888
def fire_action_event
  return unless @list
  return unless @table_row_sorter
  require 'canis/core/include/ractionevent'
  # the header event must only be used if columns passed
  if header_row?
    # TODO we need to fire correct even for header row, including
    #alert "you are on header row: #{@columns[x]} curpos: #{@curpos}, x:#{x} "
    #aev = TextActionEvent.new self, :PRESS, @columns[x], x, @curpos
    x = _convert_curpos_to_column
    @table_row_sorter.toggle_sort_order x
    @table_row_sorter.sort
    @repaint_required = true
    aev = TextActionEvent.new self, :PRESS,:header, x, @curpos
  else
    # please check this again current_value due to _header_adjustment XXX test
    aev = TextActionEvent.new self, :PRESS, current_value(), @current_index, @curpos
  end
  fire_handler :PRESS, aev
end
get_content() click to toggle source

FOR scrollable ###

# File lib/canis/core/widgets/deprecated/tabularwidget.rb, line 401
def get_content
  @list
  #[:columns, :separator,  *@list]
  #[:columns, *@list]
end
getvalue() click to toggle source
# File lib/canis/core/widgets/deprecated/tabularwidget.rb, line 417
def getvalue
  @list
end
header_row?() click to toggle source

returns true if cursor is on header row NOTE: I have no idea why row was used here. it is not working

# File lib/canis/core/widgets/deprecated/tabularwidget.rb, line 876
def header_row?
  return false if @columns.nil?
  #1 == @row + (@current_index-@toprow)
  @current_index == @toprow
end
headings=(array)
Alias for: columns=
insert(off0, *data) click to toggle source
# File lib/canis/core/widgets/deprecated/tabularwidget.rb, line 234
def insert off0, *data
  @repaint_required = true
  @list.insert off0, *data
end
load_module(requirename, includename) click to toggle source

dynamically load a module and execute init method. Hopefully, we can get behavior like this such as vieditable or multibuffers TODO CUT THIS OUT AND FIX IT, there are simpler ways like extend()

# File lib/canis/core/widgets/deprecated/tabularwidget.rb, line 868
def load_module requirename, includename
  require "canis/#{requirename}"
  extend Object.const_get("#{includename}")
  send("#{requirename}_init") #if respond_to? "#{includename}_init"
end
map_keys() click to toggle source
# File lib/canis/core/widgets/deprecated/tabularwidget.rb, line 147
def map_keys
  require 'canis/core/include/deprecated/listbindings'
  bindings()
  bind_key(?w, :next_column)
  bind_key(?b, :previous_column)
  bind_key(?>, :expand_column) # just trying out
  list_bindings # selection bindings
end
move_column() click to toggle source
# File lib/canis/core/widgets/deprecated/tabularwidget.rb, line 311
def move_column

end
next_column() click to toggle source

move cursor to next column FIXME need to account for hidden columns and numbering

# File lib/canis/core/widgets/deprecated/tabularwidget.rb, line 936
def next_column
  c = @column_pointer.next
  cp = @coffsets[c] 
  #$log.debug " next_column #{c} , #{cp} "
  @curpos = cp if cp
  next_row() if c < @column_pointer.last_index
  #addcol cp
  set_form_col 
end
on_enter() click to toggle source
Calls superclass method
# File lib/canis/core/widgets/deprecated/tabularwidget.rb, line 924
def on_enter
  # so cursor positioned on correct row
  set_form_row
  super
end
on_enter_row(arow) click to toggle source

called by listscrollable, used by scrollbar ENTER_ROW

# File lib/canis/core/widgets/deprecated/tabularwidget.rb, line 930
def on_enter_row arow
  fire_handler :ENTER_ROW, self
  @repaint_required = true
end
previous_column() click to toggle source
# File lib/canis/core/widgets/deprecated/tabularwidget.rb, line 945
def previous_column
  c = @column_pointer.previous
  cp = @coffsets[c] 
  #$log.debug " prev_column #{c} , #{cp} "
  @curpos = cp if cp
  previous_row() if c > @column_pointer.last_index
  #addcol cp FIXME
  set_form_col 
end
print_data_row(r, c, len, value, color, attr) click to toggle source

print data rows

print_header() click to toggle source

prints the column headers Uses convert_value_to_text and print_header_row

print_header_row(r, c, len, value, color, attr) click to toggle source

print header row

allows user to override
real_index() click to toggle source
# File lib/canis/core/widgets/deprecated/tabularwidget.rb, line 426
def real_index
  @current_index-@_header_adjustment # XXX added header_adju 2010-11-06 19:38
end
remove_all() click to toggle source
# File lib/canis/core/widgets/deprecated/tabularwidget.rb, line 218
def remove_all
  @list = []
  init_vars
end
row_count() click to toggle source
# File lib/canis/core/widgets/deprecated/tabularwidget.rb, line 344
def row_count
  #@list.length
  get_content().length + @_header_adjustment
end
separator() click to toggle source
# File lib/canis/core/widgets/deprecated/tabularwidget.rb, line 709
def separator
  #return @separ if @separ
  str = ""
  if @numbering
    rows = @list.size.to_s.length
    str = "-"*(rows+1)+@x
  end
  @cw.each_pair { |k,v| str << "-" * (v+1) + @x }
  @separ = str.chop
end
set_content(list, columns=nil) click to toggle source

send in a list of data sorting will only happen if data passed using set_content NOTE: why doesn't set_content take in columns @param [Array / Tabular] data to be displayed

# File lib/canis/core/widgets/deprecated/tabularwidget.rb, line 176
def set_content list, columns=nil
  if list.is_a? Canis::Tabular
    @list = list
  elsif list.is_a? Array
    @list = list
  else
    raise "set_content expects Array not #{list.class}"
  end
  if @table_row_sorter
    @table_row_sorter.model=@list
  else
    @table_row_sorter = TableRowSorter.new @list
  end
  # adding columns setting here 2011-10-16
  self.columns = columns if columns
  @current_index = @_header_adjustment # but this is set when columns passed
  @toprow = 0
  @second_time = false # so that reestimation of column_widths
  @repaint_required = true
  @recalc_required = true # is this used, if not remove TODO
  self
end
top_row(*val) click to toggle source
display this row number on top

programmataically indicate a row to be top row

# File lib/canis/core/widgets/deprecated/tabularwidget.rb, line 327
def top_row(*val) 
  if val.empty?
    @toprow
  else
    @toprow = val[0] || 0
  end
  @repaint_required = true
end
undo_delete() click to toggle source

undo deleted row/rows, this is a simple undo, unlike undo_managers more complete undo. I am not calling this undo, so there's no conflict with undomanager if used. NOTE: user has to map this to some key such as 'u'

tw.bind_key(?\U) { tw.undo }
# File lib/canis/core/widgets/deprecated/tabularwidget.rb, line 272
def undo_delete
  return unless @delete_buffer
  if @delete_buffer[0].is_a? Array
    # multiple rows deleted
    insert real_index(), *@delete_buffer
  else
    # one row deleted
    insert real_index(), @delete_buffer
  end
end

Private Instance Methods

column_name(index)
Alias for: get_column_name
get_column_name(index) click to toggle source
# File lib/canis/core/widgets/deprecated/tabularwidget.rb, line 1080
def get_column_name index
  @columns[index]
end
Also aliased as: column_name
method_missing(name, *args) click to toggle source
# File lib/canis/core/widgets/deprecated/tabularwidget.rb, line 1085
def method_missing(name, *args)
  name = name.to_s
  case name 
  when 'cell_editing_allowed', 'editing_policy'
    # silently ignore to keep compatible with Table
  else
    raise NoMethodError, "Undefined method #{name} for TabularWidget"
  end
end
set_data(data, colnames_array) click to toggle source

for some compatibility with Table

# File lib/canis/core/widgets/deprecated/tabularwidget.rb, line 1076
def set_data data, colnames_array
  set_content data
  columns = colnames_array
end