Module: Canis

Extended by:
Canis
Includes:
ColorMap
Included in:
Canis
Defined in:
lib/canis/core/util/viewer.rb,
lib/canis.rb,
lib/canis/version.rb,
lib/canis/core/util/app.rb,
lib/canis/core/include/io.rb,
lib/canis/core/widgets/box.rb,
lib/canis/core/widgets/tree.rb,
lib/canis/core/system/window.rb,
lib/canis/core/widgets/rlink.rb,
lib/canis/core/widgets/rmenu.rb,
lib/canis/core/widgets/table.rb,
lib/canis/core/include/action.rb,
lib/canis/core/system/ncurses.rb,
lib/canis/core/util/textutils.rb,
lib/canis/core/widgets/rcombo.rb,
lib/canis/core/system/colormap.rb,
lib/canis/core/util/ansiparser.rb,
lib/canis/core/util/promptmenu.rb,
lib/canis/core/widgets/divider.rb,
lib/canis/core/widgets/listbox.rb,
lib/canis/core/widgets/rwidget.rb,
lib/canis/core/widgets/tabular.rb,
lib/canis/core/widgets/textpad.rb,
lib/canis/core/include/rhistory.rb,
lib/canis/core/util/helpmanager.rb,
lib/canis/core/util/focusmanager.rb,
lib/canis/core/widgets/rmenulink.rb,
lib/canis/core/widgets/rprogress.rb,
lib/canis/core/widgets/scrollbar.rb,
lib/canis/core/include/appmethods.rb,
lib/canis/core/include/vieditable.rb,
lib/canis/core/include/widgetmenu.rb,
lib/canis/core/widgets/listfooter.rb,
lib/canis/core/widgets/rcontainer.rb,
lib/canis/core/widgets/statusline.rb,
lib/canis/core/include/bordertitle.rb,
lib/canis/core/include/canisparser.rb,
lib/canis/core/include/colorparser.rb,
lib/canis/core/include/multibuffer.rb,
lib/canis/core/util/rcommandwindow.rb,
lib/canis/core/widgets/rmessagebox.rb,
lib/canis/core/widgets/rtabbedpane.rb,
lib/canis/core/include/listbindings.rb,
lib/canis/core/include/ractionevent.rb,
lib/canis/core/include/rchangeevent.rb,
lib/canis/core/include/textdocument.rb,
lib/canis/core/util/widgetshortcuts.rb,
lib/canis/core/include/actionmanager.rb,
lib/canis/core/util/extras/padreader.rb,
lib/canis/core/widgets/rtabbedwindow.rb,
lib/canis/core/include/listoperations.rb,
lib/canis/core/util/extras/bottomline.rb,
lib/canis/core/widgets/tree/treemodel.rb,
lib/canis/core/include/rinputdataevent.rb,
lib/canis/core/util/defaultcolorparser.rb,
lib/canis/core/util/oldwidgetshortcuts.rb,
lib/canis/core/widgets/keylabelprinter.rb,
lib/canis/core/widgets/deprecated/rlist.rb,
lib/canis/core/widgets/deprecated/rtree.rb,
lib/canis/core/widgets/extras/rtextarea.rb,
lib/canis/core/widgets/applicationheader.rb,
lib/canis/core/include/listselectionmodel.rb,
lib/canis/core/system/deprecated/keyboard.rb,
lib/canis/core/widgets/deprecated/rtextview.rb,
lib/canis/core/widgets/tree/treecellrenderer.rb,
lib/canis/core/widgets/deprecated/tabularwidget.rb,
lib/canis/core/include/deprecated/listscrollable.rb,
lib/canis/core/include/deprecated/listselectable.rb,
lib/canis/core/include/deprecated/listcellrenderer.rb

Overview

File created: 2010-10-29 14:09 Author : jkepler

this is a new, simpler version of listselectable the original gets into models and has complicated operation as well as difficult to remember method names. This attempts to be a simple plugin. Currently being used by rbasiclistbox (rlist) and now tabularwidget. NOTE: pls define @_header_adjustment to 0 if you don’t use it or know what it means. TODO: of course we need to fire events so user can do something.

Defined Under Namespace

Modules: BorderTitle, Chunks, ColorMap, ConfigSetup, DefaultListSelection, EventHandler, FieldHistory, FocusManager, Io, KeyDispatcher, Keyboard, ListBindings, ListOperations, ListScrollable, MultiBuffers, NewListSelectable, TextUtils, Utils, ViEditable, WidgetMenu, WidgetShortcuts Classes: AbstractTextPadRenderer, Action, ActionEvent, ActionManager, AnsiParser, App, ApplicationHeader, Bottomline, Box, Button, ButtonGroup, CMenuItem, CanisParser, ChangeEvent, CheckBox, CheckBoxMenuItem, Circular, ColumnInfo, ColumnResizeEvent, ComboBox, CommandWindow, Container, ControlPHandler, DefaultColorParser, DefaultKeyHandler, DefaultKeyReader, DefaultListSelectionModel, DefaultRenderer, DefaultTableRenderer, DefaultTableRowSorter, DefaultTreeModel, DefaultTreeRenderer, Divider, DragEvent, Field, FieldValidationException, Form, HelpManager, History, IllegalStateException, InputDataEvent, ItemEvent, KeyLabelPrinter, Label, LabeledField, Link, List, ListCellRenderer, ListFooter, ListRenderer, ListSelectionEvent, Listbox, Menu, MenuBar, MenuItem, MenuLink, MenuSeparator, MessageBox, PadReader, PrefixCommand, Progress, PromptMenu, PropertyChangeEvent, PropertyVetoException, RadioButton, Scrollbar, StatusLine, Tab, TabButton, TabbedPane, TabbedWindow, Table, Tabular, TabularWidget, TextActionEvent, TextArea, TextDocument, TextPad, TextView, ToggleButton, Tree, TreeCellRenderer, TreeModelEvent, TreeNode, TreeSelectionEvent, Variable, Viewer, Widget, Window

Constant Summary collapse

VERSION =
"0.0.8"
CANIS_DOCPATH =
File.dirname(File.dirname(__FILE__)) + "/docs/"

Class Method Summary collapse

Instance Method Summary collapse

Methods included from ColorMap

colors, get_color, get_color_const, get_colors_for_pair, install_color, is_color?, reset_color_id, setup

Class Method Details

.start_ncursesObject

Setup ncurses, nicely documented by the curses manpages



7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
# File 'lib/canis/core/system/ncurses.rb', line 7

def start_ncurses
  return if $ncurses_started
  $ncurses_started = true
  # in case we want a blocking getch, you may want to first
  # set wtimeout to -1, and then reset it to this value.
  # Please first check that we are using this.
  $ncurses_timeout = 500 # used by windows for timeout of wgetch

  # The initscr code determines the terminal type and initializes all curses
  # data structures.
  # initscr also causes the first call to refresh to clear the screen.
  # If errors occur, initscr writes an appropriate error message to standard
  # error and exits; otherwise, a pointer is returned to stdscr.
  stdscr = Ncurses.initscr  ## FFI

#    Color.start if Ncurses.has_colors?
    Ncurses.start_color();
    ColorMap.setup # added by RK 2008-11-30 00:48 
  # The keypad option enables the keypad of the user's terminal.
  # If enabled (bf is TRUE), the user can press a function key (such as an
  # arrow key) and wgetch returns a single value representing the function
  # key, as in KEY_LEFT.
  # If disabled (bf is FALSE), curses does not treat function keys specially
  # and the program has to interpret the escape sequences itself.
  # If the keypad in the terminal can be turned on (made to transmit) and off
  # (made to work locally), turning on this option causes the terminal keypad
  # to be turned on when wgetch is called.
  # The default value for keypad is false.
  Ncurses.keypad(stdscr.pointer, bf = true) # FFIWINDOW
  #Ncurses.keypad(stdscr, bf = true)
    #Ncurses.stdscr.keypad(true)     # turn on keypad mode FFI
  #Ncurses.keypad(stdscr, bf = 1)

  # The nl and nonl routines control whether the underlying display device
  # translates the return key into newline on input, and whether it
  # translates newline into return and line-feed on output (in either case,
  # the call addch('\n') does the equivalent of return and line feed on the
  # virtual screen).
  # Initially, these translations do occur.
  # If you disable them using nonl, curses will be able to make better use of
  # the line-feed capability, resulting in faster cursor motion.
  # Also, curses will then be able to detect the return key.
  Ncurses.nonl

  # The raw and noraw routines place the terminal into or out of raw mode.
  # Raw mode is similar to cbreak mode, in that characters typed are
  # immediately passed through to the user program.
  # The differences are that in raw mode, the interrupt, quit, suspend, and
  # flow control characters are all passed through uninterpreted, instead of
  # generating a signal.
  # The behavior of the BREAK key depends on other bits in the tty driver
  # that are not set by curses.
  Ncurses.raw

  # Normally, the tty driver buffers typed characters until a newline or
  # carriage return is typed.
  # The cbreak routine disables line buffering and
  # erase/kill character-processing (interrupt and flow control characters
  # are unaffected), making characters typed by the user immediately
  # available to the program.
  #Ncurses.cbreak
  # I have removed cbreak and halfdelay since they were causing C-c
  # to crash if i pressed it in succession

  # The echo and noecho routines control whether characters typed by the user
  # are echoed by getch as they are typed.
  # Echoing by the tty driver is always disabled, but initially getch is in
  # echo mode, so characters typed are echoed.
  Ncurses.noecho

  # The curs_set routine sets the cursor state is set to invisible, normal,
  # or very visible for visibility equal to 0, 1, or 2 respectively.
  # If the terminal supports the visibility requested, the previous cursor
  # state is returned; otherwise, ERR is returned.
  Ncurses.curs_set(1)

  # The halfdelay routine is used for half-delay mode, which is similar to
  # cbreak mode in that characters typed by the user are immediately
  # available to the  program.
  # However, after blocking for tenths tenths of seconds, ERR is returned if
  # nothing has been typed.
  # The value of tenths must be a number between 1 and 255.
  # Use nocbreak to leave half-delay mode.
  #Ncurses::halfdelay(tenths = 10)
  # See above why switched off, halfdelay puts into cbreak mode, in which C-c pressed in quick
  # succession crashes the program.

  # The nodelay option causes getch to be a non-blocking call. If no input is
  # ready, getch returns ERR. If disabled (bf is FALSE), getch waits until a
  # key is pressed.
  # I am using the next line for the window when creating, this does not
  # have any impact on window.
  # For this to have any effect your getch should be Ncurses.getch and not
  # wgetch(@window), For that do this with window.
  # I am disableing this 2011-12-20 since it does not work with combinations
  # such as gg. Any routine that does a getch will just immediatelt return an ERR.
  #Ncurses::nodelay(stdscr.pointer, bf = true)


  # added these 2 so we can do resizing based on original and current size when terminal resized
  #  2012-01-8 
  $orig_cols = FFI::NCurses.COLS
  $orig_rows = FFI::NCurses.LINES
  # cache of keycode (int) and string result
  $key_cache ||= {}
end

.startupObject

unused to my knowledge

Since:

  • 1.2.0



3644
3645
3646
3647
3648
3649
3650
3651
# File 'lib/canis/core/widgets/rwidget.rb', line 3644

def self.startup
  raise "startup seems to be unused. remove this line if used, else remove method by next version"
  Canis::start_ncurses
  path = File.join(ENV["LOGDIR"] || "./" ,"canis14.log")
  file   = File.open(path, File::WRONLY|File::TRUNC|File::CREAT) 
  $log = Logger.new(path)
  $log.level = Logger::DEBUG
end

.stop_ncursesObject

this should happen only in outermost program that started ncurses if a called program does this, the calling program can have a display freeze



116
117
118
119
120
121
122
123
124
125
126
127
128
129
# File 'lib/canis/core/system/ncurses.rb', line 116

def stop_ncurses
  Ncurses.echo
  Ncurses.nocbreak
  Ncurses.nl
  Ncurses.endwin
  $ncurses_started = false
  #puts "curses over"
ensure
  return unless error = @last_error

  $stderr.puts ''
  $stderr.puts @last_error_message if @last_error_message
  $stderr.puts @last_error, *@last_error.backtrace
end

Instance Method Details

#_new_layout(size) ⇒ Object

create a new layout array based on size of data given The layout created is weighted to the bottom, so it is always ending at the second last row The top keeps changing based on height.



706
707
708
709
710
711
712
# File 'lib/canis/core/util/rcommandwindow.rb', line 706

def _new_layout size
  ht = size
  #ht = 15
  sh = Ncurses.LINES-1
  sc = Ncurses.COLS-0
  layout = [ ht, sc, sh-ht ,0]
end

#_update_default_settings(config = {}) ⇒ Object

update given hash with layout, close_key and app_header so this is shared across various methods. The layout created is weighted to the bottom, so it is always ending at the second last row



690
691
692
693
694
695
696
697
698
699
700
701
702
# File 'lib/canis/core/util/rcommandwindow.rb', line 690

def _update_default_settings config={}
  ht = config[:height] || 15
  sh = Ncurses.LINES-1
  sc = Ncurses.COLS-0
  layout = [ ht, sc, sh-ht ,0]
  config[:layout] = layout
  config[:close_key] = KEY_ENTER
  config[:app_header] = true
  # repeated resetting seems to play with left and other things.
  # let's say we know that my window will always have certain settings, then let me do a check for them in padrefresh
  # in this window the only thing changing is the top (based on rows). all else is same.
  #config[:fixed_bounds] = [nil, 0, sh, sc]
end

#choose_file(glob, config = {}) ⇒ Object

This is a variation of display_list which is more for selecting a file, or dir. It maps some keys to go up to parent dir, and to step into directory under cursor if you are in directory mode. NOTE: if you pass a glob, then :recursive will not apply. You must specify recursive by prepending “**/” or inserting it in the appropriate place such as “a/b/c/**/*rb”. We would not know where to place the “**/”.

Examples:

list directories recursively


str = choose_file  :title => "Select a file", 
   :recursive => true,
   :dirs => true,

Parameters:

  • (optional) (String)

    glob is a glob to apply when creating a listing

  • config (Hash) (defaults to: {})

    options for configuring the listing

Options Hash (config):

  • :recursive (Boolean)

    Should listing recurse, default true

  • :dirs (Boolean)

    Should list directories only, default false

  • :startdir (String)

    Directory to use as current You may also add other config pairs to be passed to textpad such as title



607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
# File 'lib/canis/core/util/rcommandwindow.rb', line 607

def choose_file glob, config={}
  if glob.is_a? Hash
    config = glob
    glob = nil
  end
  frec = true
  frec = config.delete :recursive if config.key? :recursive
  fdir = config.delete :dirs
  if glob.nil?
    glob = "*"
    if frec
      glob = "**/*"
    end
    if fdir
      glob << "/"
    end
  end
  maxh = 15
  # i am not going through that route, since going up and down a dir will be difficult in a generic
  # case the glob has the dir in it, or i pass directory to the handler.
  # why not Dir.pwd in next line ?? XXX
  #directory = Pathname.new(File.expand_path(File.dirname($0)))
  #_d = config.delete :directory
  #if _d
    #directory = Pathname.new(File.expand_path(_d))
  #end
  directory = config.delete :directory
  # this keeps going up with each invocation if I send ".."
  Dir.chdir(directory) if directory
  command = config.delete(:command)
  text = Dir.glob(glob)
  #text = Dir[File.join(directory.to_s, glob)]
  if !text or text.empty?
    text = ["No entries"]
  end
  if text.size < maxh
    config[:height] = text.size + 1
  end
  # calc window coords
  _update_default_settings config
  default_layout = config[:layout]
  config[:close_key] = 1001
  command_list(text, config) do |t, hash|
    t.suppress_borders true
    t.print_footer false
    #t.fixed_bounds config.delete(:fixed_bounds)
    t.key_handler = ControlPHandler.new(t)
    t.key_handler.maxht = maxh
    t.key_handler.default_layout = default_layout
    t.key_handler.header = hash[:header]
    t.key_handler.recursive_search(glob)
    t.key_handler.directory_key_map
  end
end

#command_list(content, config = {}, &block) ⇒ Object

this is taken from view and replaces the call to view, since we were modifying view a bit too much to fit it into the needs here.



30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
# File 'lib/canis/core/util/rcommandwindow.rb', line 30

def command_list content, config={}, &block  #:yield: textpad
  wt = 0 # top margin
  wl = 0 # left margin
  wh = Ncurses.LINES-wt # height, goes to bottom of screen
  ww = Ncurses.COLS-wl  # width, goes to right end
  layout = { :height => wh, :width => ww, :top => wt, :left => wl } 
  if config.has_key? :layout
    layout = config[:layout]
    case layout
    when Array
      wh, ww, wt, wl = layout
      layout = { :height => wh, :width => ww, :top => wt, :left => wl } 
    when Hash
      # okay
    end
  end

  fp = config[:title] || ""
  pf = config.fetch(:print_footer, false)
  ta = config.fetch(:title_attrib, 'bold')
  fa = config.fetch(:footer_attrib, 'bold')
  b_ah = config[:app_header]
  type = config[:content_type]

  v_window = Canis::Window.new(layout)
  v_form = Canis::Form.new v_window
  v_window.name = "command-list"
  colors = Ncurses.COLORS
  back = :blue
  back = 235 if colors >= 256
  blue_white = get_color($datacolor, :white, back)

  tprow = 0
  ah = nil
  if b_ah
    ah = ApplicationHeader.new v_form, "", :text_center => fp
    tprow += 1
  end

  textview = TextPad.new v_form do
    name   "CommandList" 
    row  tprow
    col  0
    width ww
    height wh-tprow # earlier 2 but seems to be leaving space.
    title fp
    title_attrib ta
    print_footer pf
    footer_attrib fa
    #border_attrib :reverse
    border_color blue_white
  end

  t = textview
  items = {:header => ah}
  begin
    textview.set_content content, :content_type => type
    if block_given?
      if block.arity > 0
        yield textview, items
      else
        textview.instance_eval(&block)
      end
    end
  v_form.repaint
  v_window.wrefresh
  Ncurses::Panel.update_panels
  retval = ""
  # allow closing using q and Ctrl-q in addition to any key specified
  #  user should not need to specify key, since that becomes inconsistent across usages
  #  NOTE: no longer can we close with just a q since often apps using this trap char keys
  #  NOTE: 2727 is no longer operational, so putting just ESC
    while((ch = v_window.getchar()) != ?\C-q.getbyte(0) )
      # ideally we should be throwing a close rather than this since called will need keys.
      retval = textview.current_value() if ch == config[:close_key] 
      break if ch == config[:close_key] || ch == 3|| ch == 27 # removed double esc 2014-05-04 - 17:30 
      # if you've asked for ENTER then i also check for 10 and 13
      retval = textview.current_value() if (ch == 10 || ch == 13) && config[:close_key] == KEY_ENTER
      break if (ch == 10 || ch == 13) && config[:close_key] == KEY_ENTER
      v_form.handle_key ch
      v_form.repaint
    end
  rescue => err
      $log.error " command-list ERROR #{err} "
      $log.debug(err.backtrace.join("\n"))
      alert "#{err}"
      #textdialog ["Error in command-list: #{err} ", *err.backtrace], :title => "Exception"
  ensure
    v_window.destroy if !v_window.nil?
  end
  return retval
end

#display_list(text, config = {}) ⇒ String

return a blank if user quits list, or the value can we prevent a user from quitting, he must select ?

Display a list of valies given in text and allows user to shrink the list based on keys entered much like control-p.

x show keys entered x shrink the pad based on results x if no results show somethinf like “No entries”. or don’t change TODO take left and right arrow key and adjust insert point TODO have some proc so user can keep querying, rather than passing a list. this way if the list is really long, all values don’t need to be passed.

Parameters:

  • array (Array<String>)

    of Strings to print

  • config (Hash) (defaults to: {})

    hash passed to Viewer.view May contain :command which is a Proc that replenishes the list everytime user enters a key (updates the search string). The proc is supplied user-entered string. The following example is a proc that matches all the files returned by Dir.glob with the user entered string.

    Proc.new {|str| Dir.glob("**/*").select do |p| p.index str; end }
    

Returns:

  • (String)

    text of line user pressed ENTER on, or “” if user pressed ESC or C-c



735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
# File 'lib/canis/core/util/rcommandwindow.rb', line 735

def display_list text, config={}
  maxh = 15
  _update_default_settings config
  default_layout = config[:layout].dup
  command = config.delete(:command)
  command_list(text, config) do |t, hash|
    t.suppress_borders true
    t.print_footer false
    #t.fixed_bounds config.delete(:fixed_bounds)
    t.key_handler = ControlPHandler.new(t)
    t.key_handler.maxht = maxh
    t.key_handler.default_layout = default_layout
    t.key_handler.header = hash[:header]
    t.key_handler.command = command if command
  end
end

#display_text(text, config = {}) ⇒ Object

NOTE: moved from bottomline since it used commandwindow but now we;ve moved away from ListObject to view. and i wonder what this really gives ? WARNING: if you actually use this, please copy it to your app, since it may be removed. I don;t see what real purpose it achieves. It is now a wrapper over Canis::Viewer.view

Displays text at the bottom of the screen, close the screen with ENTER. and defaults to 15. All other config elements are passed to view. See viewer.rb.

Parameters:

  • text

    can be file name or Array of Strings.

  • config (defaults to: {})

    is a Hash. :height which will be from bottom of screen



675
676
677
678
679
680
681
682
683
684
685
686
# File 'lib/canis/core/util/rcommandwindow.rb', line 675

def display_text text, config={}
  _update_default_settings config
  if text.is_a? String
    if File.exists? text
      text = File.open(text, 'r').read.split("\n")
    end
  end
  command_list(text, config) do |t|
    t.suppress_borders true
    t.print_footer false
  end
end

#numbered_menu(list1, config = {}) ⇒ Array

presents given list in numbered format in a window above last line and accepts input on last line The list is a list of strings. e.g.

%w{ ruby perl python haskell }

Multiple levels can be given as:

list = %w{ ruby perl python haskell }
list[0] = %w{ ruby ruby1.9 ruby 1.8 rubinius jruby }

In this case, “ruby” is the first level option. The others are used in the second level. This might make it clearer. first3 has 2 choices under it.

[ "first1" , "first2", ["first3", "second1", "second2"], "first4"]

Currently, we return an array containing each selected level

Returns:

  • (Array)

    selected option/s from list



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
576
577
578
579
580
581
582
583
584
585
# File 'lib/canis/core/util/rcommandwindow.rb', line 545

def numbered_menu list1, config={}
  if list1.nil? || list1.empty?
    #say_with_pause "empty list passed to numbered_menu"  # 2014-04-25
     # remove bottomline
    print_error_message "Empty list passed to numbered_menu"
    return nil
  end
  prompt = config[:prompt] || "Select one: "
  require 'canis/core/util/rcommandwindow'
  layout = { :height => 5, :width => Ncurses.COLS-1, :top => Ncurses.LINES-6, :left => 0 }
  rc = CommandWindow.new nil, :layout => layout, :box => true, :title => config[:title]
  w = rc.window
  # should we yield rc, so user can bind keys or whatever
  # attempt a loop so we do levels.
  retval = []
  begin
    while true
      rc.display_menu list1, :indexing => :number
      #ret = ask(prompt, Integer ) { |q| q.in = 1..list1.size }
      # if class is specifited then update type in Field
      ret = rb_gets(prompt) {|f| f.datatype = 1.class ; f.type :integer; f.valid_range(1..list1.size)}
      val = list1[ret-1]
      if val.is_a? Array
        retval << val[0]
        $log.debug "NL: #{retval} "
        list1 = val[1..-1]
        rc.clear
      else
        retval << val
        $log.debug "NL1: #{retval} "
        break
      end
    end
  ensure
    rc.destroy
    rc = nil
  end
  #list1[ret-1]
  $log.debug "NL2: #{retval} , #{retval.class} "
  retval
end

#repaint_oldObject



115
116
# File 'lib/canis/core/widgets/rprogress.rb', line 115

def repaint_old
end