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
@endgroup select related
dsl_accessor :suppress_borders
boolean, whether lines should be numbered
index of selected rows, if multiple selection asked for
default or custom sorter
Public Class Methods
# 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
# File lib/canis/core/widgets/deprecated/tabularwidget.rb, line 231 def [](off0) @list[off0] end
# File lib/canis/core/widgets/deprecated/tabularwidget.rb, line 227 def []=(off0, data) @repaint_required = true @list[off0] = data end
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
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
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
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
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
# 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 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
# 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
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
# File lib/canis/core/widgets/deprecated/tabularwidget.rb, line 198 def data=(data) set_content(data, nil) end
# 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 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
# 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
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
FOR scrollable ###
# File lib/canis/core/widgets/deprecated/tabularwidget.rb, line 401 def get_content @list #[:columns, :separator, *@list] #[:columns, *@list] end
# File lib/canis/core/widgets/deprecated/tabularwidget.rb, line 417 def getvalue @list end
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
# File lib/canis/core/widgets/deprecated/tabularwidget.rb, line 234 def insert off0, *data @repaint_required = true @list.insert off0, *data end
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
# 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
# File lib/canis/core/widgets/deprecated/tabularwidget.rb, line 311 def move_column end
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
# File lib/canis/core/widgets/deprecated/tabularwidget.rb, line 924 def on_enter # so cursor positioned on correct row set_form_row super end
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
# 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 rows
# File lib/canis/core/widgets/deprecated/tabularwidget.rb, line 675 def print_data_row r, c, len, value, color, attr @graphic.printstring r, c, "%-*s" % [len,value], color, attr end
prints the column headers Uses convert_value_to_text
and print_header_row
# File lib/canis/core/widgets/deprecated/tabularwidget.rb, line 721 def print_header r,c = rowcol value = convert_value_to_text :columns, 0 len = @width - @internal_width truncate value # else it can later suddenly exceed line @header_color_pair ||= get_color $promptcolor, @header_fgcolor, @header_bgcolor @header_attrib ||= @attr print_header_row r, c, len, value, @header_color_pair, @header_attrib end
print header row
allows user to override
# File lib/canis/core/widgets/deprecated/tabularwidget.rb, line 705 def print_header_row r, c, len, value, color, attr #acolor = $promptcolor @graphic.printstring r, c+@left_margin, "%-*s" % [len-@left_margin ,value], color, attr end
# 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
# File lib/canis/core/widgets/deprecated/tabularwidget.rb, line 218 def remove_all @list = [] init_vars end
# File lib/canis/core/widgets/deprecated/tabularwidget.rb, line 344 def row_count #@list.length get_content().length + @_header_adjustment end
# 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
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
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 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
# File lib/canis/core/widgets/deprecated/tabularwidget.rb, line 1080 def get_column_name index @columns[index] end
# 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
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