rbcurse 1.5.2 → 1.5.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (100) hide show
  1. data/README.markdown +3 -2
  2. data/VERSION +1 -1
  3. metadata +6 -103
  4. data/examples/README.txt +0 -67
  5. data/examples/abasiclist.rb +0 -33
  6. data/examples/alpmenu.rb +0 -42
  7. data/examples/app.rb +0 -859
  8. data/examples/app.sample +0 -17
  9. data/examples/appdirtree.rb +0 -74
  10. data/examples/appemail.rb +0 -191
  11. data/examples/appemaillb.rb +0 -308
  12. data/examples/appgcompose.rb +0 -315
  13. data/examples/atree.rb +0 -64
  14. data/examples/common/file.rb +0 -40
  15. data/examples/common/rmail.rb +0 -257
  16. data/examples/data.txt +0 -683
  17. data/examples/data/README.markdown +0 -9
  18. data/examples/data/brew.txt +0 -38
  19. data/examples/data/color.2 +0 -37
  20. data/examples/data/gemlist.txt +0 -60
  21. data/examples/data/lotr.txt +0 -12
  22. data/examples/data/ports.txt +0 -136
  23. data/examples/data/tasks.txt +0 -27
  24. data/examples/data/todocsv.csv +0 -28
  25. data/examples/data/unix1.txt +0 -21
  26. data/examples/data/unix2.txt +0 -11
  27. data/examples/dbdemo.rb +0 -495
  28. data/examples/deprecated/appgmail.rb +0 -952
  29. data/examples/deprecated/splitp.rb +0 -56
  30. data/examples/deprecated/testscrolllb.rb +0 -86
  31. data/examples/deprecated/testscrollp.rb +0 -88
  32. data/examples/deprecated/testscrollta.rb +0 -80
  33. data/examples/deprecated/testscrolltable.rb +0 -165
  34. data/examples/deprecated/testsplit.rb +0 -87
  35. data/examples/deprecated/testsplit2.rb +0 -123
  36. data/examples/deprecated/testsplit3.rb +0 -215
  37. data/examples/deprecated/testsplit3_1.rb +0 -244
  38. data/examples/deprecated/testsplit3a.rb +0 -215
  39. data/examples/deprecated/testsplit3b.rb +0 -237
  40. data/examples/deprecated/testsplitta.rb +0 -148
  41. data/examples/deprecated/testsplittv.rb +0 -142
  42. data/examples/deprecated/testsplittvv.rb +0 -144
  43. data/examples/deprecated/testtpane.rb +0 -215
  44. data/examples/deprecated/testtpane2.rb +0 -145
  45. data/examples/deprecated/testtpanetable.rb +0 -203
  46. data/examples/dirtree.rb +0 -88
  47. data/examples/experimental/resultsetdemo.rb +0 -280
  48. data/examples/experimental/testmform.rb +0 -35
  49. data/examples/experimental/testscroller.rb +0 -117
  50. data/examples/experimental/teststackflow.rb +0 -111
  51. data/examples/menu1.rb +0 -112
  52. data/examples/multispl.rb +0 -86
  53. data/examples/newmessagebox.rb +0 -131
  54. data/examples/newtabbedwindow.rb +0 -100
  55. data/examples/newtesttabp.rb +0 -121
  56. data/examples/qdfilechooser.rb +0 -68
  57. data/examples/rfe.rb +0 -1239
  58. data/examples/rfe_renderer.rb +0 -121
  59. data/examples/sqlc.rb +0 -454
  60. data/examples/sqlm.rb +0 -437
  61. data/examples/sqlt.rb +0 -408
  62. data/examples/status.txt +0 -68
  63. data/examples/table1.rb +0 -24
  64. data/examples/term2.rb +0 -84
  65. data/examples/test1.rb +0 -239
  66. data/examples/test2.rb +0 -674
  67. data/examples/testapp.rb +0 -44
  68. data/examples/testapp2.rb +0 -58
  69. data/examples/testchars.rb +0 -137
  70. data/examples/testcombo.rb +0 -91
  71. data/examples/testkeypress.rb +0 -66
  72. data/examples/testlistbox.rb +0 -113
  73. data/examples/testmenu.rb +0 -101
  74. data/examples/testmulticomp.rb +0 -70
  75. data/examples/testmulticontainer.rb +0 -94
  76. data/examples/testmultispl.rb +0 -199
  77. data/examples/testree.rb +0 -106
  78. data/examples/testtable.rb +0 -264
  79. data/examples/testtabp.rb +0 -107
  80. data/examples/testtodo.rb +0 -584
  81. data/examples/testvimsplit.rb +0 -112
  82. data/examples/testwsshortcuts.rb +0 -64
  83. data/examples/testwsshortcuts2.rb +0 -126
  84. data/examples/todo.db +0 -0
  85. data/examples/todo.yml +0 -191
  86. data/examples/viewtodo.rb +0 -574
  87. data/lib/rbcurse.rb +0 -8
  88. data/lib/rbcurse/deprecated/README.markdown +0 -12
  89. data/lib/rbcurse/deprecated/rpad.rb +0 -375
  90. data/lib/rbcurse/deprecated/rscrollpane.rb +0 -512
  91. data/lib/rbcurse/deprecated/rsplitpane.rb +0 -894
  92. data/lib/rbcurse/deprecated/rsplitpane2.rb +0 -1009
  93. data/lib/rbcurse/deprecated/rviewport.rb +0 -204
  94. data/lib/rbcurse/deprecated/widgets/mapper.rb +0 -130
  95. data/lib/rbcurse/deprecated/widgets/rmessagebox.rb +0 -348
  96. data/lib/rbcurse/deprecated/widgets/rtabbedpane.rb +0 -1158
  97. data/lib/rbcurse/deprecated/widgets/rtabbedwindow.rb +0 -167
  98. data/lib/rbcurse/deprecated/widgets/scrollable.rb +0 -301
  99. data/lib/rbcurse/deprecated/widgets/stdscrwindow.rb +0 -309
  100. data/lib/ver/keyboard2.rb +0 -170
@@ -1,131 +0,0 @@
1
- # this is a test program, tests out tabbed panes. type F1 to exit
2
- #
3
- require 'rbcurse'
4
- require 'rbcurse/core/widgets/rmessagebox'
5
-
6
- def alertme mess, config={}
7
-
8
- _title = config[:title] || "Alert"
9
- tp = Messagebox.new config do
10
- title _title
11
- button_type :ok
12
- message mess
13
- #text mess
14
- end
15
- tp.run
16
- end
17
- def textdialog mess, config={}
18
- config[:title] ||= "Alert"
19
- tp = Messagebox.new config do
20
- button_type :ok
21
- text mess
22
- end
23
- tp.run
24
- end
25
- #
26
- # FIXME needs to return field entered if OK, else nil
27
- def newget_string label, config={}
28
- config[:title] ||= "Entry"
29
- label_config = config[:label_config] || {}
30
- label_config[:row] ||= 2
31
- label_config[:col] ||= 2
32
- label_config[:text] = label
33
-
34
- field_config = config[:field_config] || {}
35
- field_config[:row] ||= 3
36
- field_config[:col] ||= 2
37
- field_config[:attr] = :reverse
38
- field_config[:maxlen] ||= config[:maxlen]
39
- field_config[:default] ||= config[:default]
40
- #field_config[:display_length] ||= 50 # i want it to extend since i don't know the actual width
41
- field_config[:width] ||= 50 # i want it to extend since i don't know the actual width
42
-
43
- tp = Messagebox.new config do
44
- button_type :ok_cancel
45
- item Label.new nil, label_config
46
- item Field.new nil, field_config
47
- end
48
- tp.run
49
- end
50
- include RubyCurses
51
- class SetupMessagebox
52
- def run
53
- $config_hash ||= Variable.new Hash.new
54
- #configvar.update_command(){ |v| $config_hash[v.source()] = v.value }
55
-
56
- #tp = Messagebox.new :row => 3, :col => 7, :width => 60, :height => 20 , :color => :white, :bgcolor => :blue do
57
- tp = Messagebox.new :color => :white, :bgcolor => :blue do
58
- title "User Setup"
59
- button_type :ok_apply_cancel
60
- item Field.new nil, :row => 2, :col => 2, :text => "enter your name", :label => ' Name: '
61
- item Field.new nil, :row => 3, :col => 2, :text => "enter your email", :label => 'Email: '
62
- r = 4
63
- item Label.new nil, :text => "Text", :row => r+1, :col => 2, :attr => :bold
64
- item CheckBox.new nil, :row => r+2, :col => 2, :text => "Antialias text"
65
- item CheckBox.new nil, :row => r+3, :col => 2, :text => "Use bold fonts"
66
- item CheckBox.new nil, :row => r+4, :col => 2, :text => "Allow blinking text"
67
- item CheckBox.new nil, :row => r+5, :col => 2, :text => "Display ANSI Colors"
68
- =begin
69
- item Label.new nil, :text => "Cursor", :row => 7, :col => 2, :attr => 'bold'
70
- $config_hash.set_value Variable.new, :cursor
71
- item RadioButton.new nil, :row => 8, :col => 2, :text => "Block", :value => "block", :variable => $config_hash[:cursor]
72
- item RadioButton.new nil, :row => 9, :col => 2, :text => "Blink", :value => "blink", :variable => $config_hash[:cursor]
73
- item RadioButton.new nil, :row => 10, :col => 2, :text => "Underline", :value => "underline", :variable => $config_hash[:cursor]
74
- end
75
- tab "&Term" do
76
-
77
- item Label.new nil, :text => "Arrow Key in Combos", :row => 2, :col => 2, :attr => 'bold'
78
- x = Variable.new
79
- $config_hash.set_value x, :term
80
- item RadioButton.new nil, :row => 3, :col => 2, :text => "ignore", :value => "ignore", :variable => $config_hash[:term]
81
- item RadioButton.new nil, :row => 4, :col => 2, :text => "popup", :value => "popup", :variable => $config_hash[:term]
82
- item RadioButton.new nil, :row => 5, :col => 2, :text => "next", :value => "next", :variable => $config_hash[:term]
83
- cb = ComboBox.new nil, :row => 7, :col => 2, :display_length => 15,
84
- :list => %w[xterm xterm-color xterm-256color screen vt100 vt102],
85
- :label => "Declare terminal as: "
86
- #radio.update_command() {|rb| ENV['TERM']=rb.value }
87
- item cb
88
- x.update_command do |rb|
89
- cb.arrow_key_policy=rb.value.to_sym
90
- end
91
-
92
- end
93
- tab "Conta&iner" do
94
- item r
95
- end
96
- # tell tabbedpane what to do if a button is pressed (ok/apply/cancel)
97
- =end
98
- command do |eve|
99
- case eve.event
100
- when 0,2 # ok cancel
101
- newget_string "Enter name: ", :default => "john", :maxlen => 50
102
- alertme "user pressed button index:#{eve.event}, #{eve.action_command} "
103
- throw :close, eve.event
104
- when 1 # apply
105
- textdialog "user pressed apply: #{eve.to_s.length} : #{eve} "
106
- end
107
- end
108
- end
109
- tp.run
110
- end
111
-
112
- end
113
- if $0 == __FILE__
114
- # Initialize curses
115
- begin
116
- # XXX update with new color and kb
117
- VER::start_ncurses # this is initializing colors via ColorMap.setup
118
- $log = Logger.new((File.join(ENV["LOGDIR"] || "./" ,"rbc13.log")))
119
- $log.level = Logger::DEBUG
120
- tp = SetupMessagebox.new()
121
- buttonindex = tp.run
122
- $log.debug "XXX: MESSAGEBOX retirned #{buttonindex} "
123
- rescue => ex
124
- ensure
125
- VER::stop_ncurses
126
- p ex if ex
127
- p(ex.backtrace.join("\n")) if ex
128
- $log.debug( ex) if ex
129
- $log.debug(ex.backtrace.join("\n")) if ex
130
- end
131
- end
@@ -1,100 +0,0 @@
1
- # this is a test program, tests out tabbed panes. type F1 to exit
2
- #
3
- require 'logger'
4
- require 'rbcurse'
5
- require 'rbcurse/core/widgets/tabbedpane'
6
- require 'rbcurse/core/widgets/rcontainer'
7
- require 'rbcurse/core/widgets/rcombo'
8
- require 'rbcurse/core/widgets/tabbedwindow'
9
-
10
- include RubyCurses
11
- class SetupTabbedPane
12
- def run
13
- $config_hash ||= Variable.new Hash.new
14
- #configvar.update_command(){ |v| $config_hash[v.source()] = v.value }
15
-
16
- r = Container.new nil, :suppress_borders => true
17
- l1 = Label.new nil, :name => "profile", :attr => 'bold', :text => "Profile"
18
- f1 = Field.new nil, :name => "name", :maxlen => 20, :display_length => 20, :bgcolor => :white,
19
- :color => :black, :text => "abc", :label => ' Name: '
20
- f2 = Field.new nil, :name => "email", :display_length => 20, :bgcolor => :white,
21
- :color => :blue, :text => "me@google.com", :label => 'Email: '
22
- f3 = RadioButton.new nil, :variable => $config_hash, :text => "red", :value => "RED", :color => :red
23
- f4 = RadioButton.new nil, :variable => $config_hash, :text => "blue", :value => "BLUE", :color => :blue
24
- f5 = RadioButton.new nil, :variable => $config_hash, :text => "green", :value => "GREEN", :color => :green
25
- r.add(l1,f1)
26
- r.add(f2)
27
- r.add(f3,f4,f5)
28
-
29
- tp = TabbedWindow.new :row => 3, :col => 7, :width => 60, :height => 20 do
30
- title "User Setup"
31
- button_type :ok_apply_cancel
32
- tab "&Profile" do
33
- item Field.new nil, :row => 2, :col => 2, :text => "enter your name", :label => ' Name: '
34
- item Field.new nil, :row => 3, :col => 2, :text => "enter your email", :label => 'Email: '
35
- end
36
- tab "&Settings" do
37
- item Label.new nil, :text => "Text", :row => 1, :col => 2, :attr => 'bold'
38
- item CheckBox.new nil, :row => 2, :col => 2, :text => "Antialias text"
39
- item CheckBox.new nil, :row => 3, :col => 2, :text => "Use bold fonts"
40
- item CheckBox.new nil, :row => 4, :col => 2, :text => "Allow blinking text"
41
- item CheckBox.new nil, :row => 5, :col => 2, :text => "Display ANSI Colors"
42
- item Label.new nil, :text => "Cursor", :row => 7, :col => 2, :attr => 'bold'
43
- $config_hash.set_value Variable.new, :cursor
44
- item RadioButton.new nil, :row => 8, :col => 2, :text => "Block", :value => "block", :variable => $config_hash[:cursor]
45
- item RadioButton.new nil, :row => 9, :col => 2, :text => "Blink", :value => "blink", :variable => $config_hash[:cursor]
46
- item RadioButton.new nil, :row => 10, :col => 2, :text => "Underline", :value => "underline", :variable => $config_hash[:cursor]
47
- end
48
- tab "&Term" do
49
-
50
- item Label.new nil, :text => "Arrow Key in Combos", :row => 2, :col => 2, :attr => 'bold'
51
- x = Variable.new
52
- $config_hash.set_value x, :term
53
- item RadioButton.new nil, :row => 3, :col => 2, :text => "ignore", :value => "ignore", :variable => $config_hash[:term]
54
- item RadioButton.new nil, :row => 4, :col => 2, :text => "popup", :value => "popup", :variable => $config_hash[:term]
55
- item RadioButton.new nil, :row => 5, :col => 2, :text => "next", :value => "next", :variable => $config_hash[:term]
56
- cb = ComboBox.new nil, :row => 7, :col => 2, :display_length => 15,
57
- :list => %w[xterm xterm-color xterm-256color screen vt100 vt102],
58
- :label => "Declare terminal as: "
59
- #radio.update_command() {|rb| ENV['TERM']=rb.value }
60
- item cb
61
- x.update_command do |rb|
62
- cb.arrow_key_policy=rb.value.to_sym
63
- end
64
-
65
- end
66
- tab "Conta&iner" do
67
- item r
68
- end
69
- # tell tabbedpane what to do if a button is pressed (ok/apply/cancel)
70
- command do |eve|
71
- alert "user pressed button index:#{eve.event} , Name: #{eve.action_command}, Tab: #{eve.source.current_tab} "
72
- case eve.event
73
- when 0,2 # ok cancel
74
- throw :close, eve.event
75
- when 1 # apply
76
- end
77
- end
78
- end
79
- tp.run
80
- end
81
-
82
- end
83
- if $0 == __FILE__
84
- # Initialize curses
85
- begin
86
- # XXX update with new color and kb
87
- VER::start_ncurses # this is initializing colors via ColorMap.setup
88
- $log = Logger.new((File.join(ENV["LOGDIR"] || "./" ,"rbc13.log")))
89
- $log.level = Logger::DEBUG
90
- tp = SetupTabbedPane.new()
91
- buttonindex = tp.run
92
- rescue => ex
93
- ensure
94
- VER::stop_ncurses
95
- p ex if ex
96
- p(ex.backtrace.join("\n")) if ex
97
- $log.debug( ex) if ex
98
- $log.debug(ex.backtrace.join("\n")) if ex
99
- end
100
- end
@@ -1,121 +0,0 @@
1
- # this is a test program, tests out tabbed panes. type F1 to exit
2
- #
3
- require 'logger'
4
- require 'rbcurse'
5
- #require 'rbcurse/core/widgets/newtabbedpane'
6
- require 'rbcurse/core/widgets/rtabbedpane'
7
-
8
- class TestTabbedPane
9
- def initialize
10
- acolor = $reversecolor
11
- #$config_hash ||= {}
12
- end
13
- def run
14
- $config_hash ||= Variable.new Hash.new
15
- #configvar.update_command(){ |v| $config_hash[v.source()] = v.value }
16
- @window = VER::Window.root_window
17
- @form = Form.new @window
18
- r = 1; c = 30;
19
- @tp = RubyCurses::TabbedPane.new @form do
20
- height 12
21
- width 50
22
- row 13
23
- col 10
24
- button_type :ok
25
- end
26
- @tab1 = @tp.add_tab "&Language"
27
- #f1 = @tab1.form
28
- f1 = @tp.form @tab1
29
- #$radio = Variable.new
30
- radio1 = RadioButton.new f1 do
31
- #variable $radio
32
- variable $config_hash
33
- name "radio1"
34
- text "ruby"
35
- value "ruby"
36
- color "red"
37
- row 4
38
- col 5
39
- end
40
- radio2 = RadioButton.new f1 do
41
- #variable $radio
42
- variable $config_hash
43
- name "radio1"
44
- text "jruby"
45
- value "jruby"
46
- color "green"
47
- row 5
48
- col 5
49
- end
50
- radio3 = RadioButton.new f1 do
51
- #variable $radio
52
- variable $config_hash
53
- name "radio1"
54
- text "macruby"
55
- value "macruby"
56
- color "cyan"
57
- row 6
58
- col 5
59
- end
60
- @tab2 = @tp.add_tab "&Settings"
61
- #f2 = @tab2.form
62
- f2 = @tp.form @tab2
63
- r = 4
64
- butts = [ "Use &HTTP/1.0", "Use &frames", "&Use SSL" ]
65
- bcodes = %w[ HTTP, FRAMES, SSL ]
66
- butts.each_with_index do |t, i|
67
- RubyCurses::CheckBox.new f2 do
68
- text butts[i]
69
- variable $config_hash
70
- name bcodes[i]
71
- row r+i
72
- col 5
73
- end
74
- end
75
- @tab3 = @tp.add_tab "&Editors"
76
- #f3 = @tab3.form
77
- f3 = @tp.form @tab3
78
- butts = %w[ &Vim E&macs &Jed &Other ]
79
- bcodes = %w[ VIM EMACS JED OTHER]
80
- row = 4
81
- butts.each_with_index do |name, i|
82
- RubyCurses::CheckBox.new f3 do
83
- text name
84
- variable $config_hash
85
- name bcodes[i]
86
- row row+i
87
- col 5
88
- end
89
- end
90
- @help = "q to quit. Use any key of key combination to see what's caught. Check logger too"
91
- RubyCurses::Label.new @form, {'text' => @help, "row" => 11, "col" => 2, "color" => "yellow"}
92
- @form.repaint
93
- @window.wrefresh
94
- Ncurses::Panel.update_panels
95
- while((ch = @window.getchar()) != ?q.getbyte(0) )
96
- # @tp.repaint
97
- @form.handle_key(ch)
98
- @window.wrefresh
99
- end
100
- #@tp.show
101
- #@tp.handle_keys
102
- end
103
- end
104
- if $0 == __FILE__
105
- # Initialize curses
106
- begin
107
- # XXX update with new color and kb
108
- VER::start_ncurses # this is initializing colors via ColorMap.setup
109
- $log = Logger.new("rbc13.log")
110
- $log.level = Logger::DEBUG
111
- n = TestTabbedPane.new
112
- n.run
113
- rescue => ex
114
- ensure
115
- VER::stop_ncurses
116
- p ex if ex
117
- p(ex.backtrace.join("\n")) if ex
118
- $log.debug( ex) if ex
119
- $log.debug(ex.backtrace.join("\n")) if ex
120
- end
121
- end
@@ -1,68 +0,0 @@
1
- # this is a test program, tests out messageboxes. type F1 to exit
2
- # a quick dirty file chooser in 2 lines of code.
3
- require 'logger'
4
- require 'rbcurse/core/system/ncurses'
5
- require 'rbcurse/core/system/window'
6
- require 'rbcurse/core/widgets/rwidget'
7
-
8
- ##
9
- # a quick dirty file chooser - only temporary till we make something better.
10
- class QDFileChooser
11
- attr_accessor :show_folders # bool
12
- attr_accessor :traverse_folders # bool
13
- attr_accessor :default_pattern # e.g. "*.*"
14
- attr_accessor :dialog_title # File Chooser
15
- def initialize
16
-
17
- end
18
- def show_open_dialog
19
- @form = RubyCurses::Form.new nil
20
- label = RubyCurses::Label.new @form, {'text' => 'File', 'row'=>3, 'col'=>4, 'color'=>'black', 'bgcolor'=>'white', 'mnemonic'=>'F'}
21
- field = RubyCurses::Field.new @form do
22
- name "file"
23
- row 3
24
- col 10
25
- display_length 40
26
- set_label label
27
- end
28
- default_pattern ||= "*.*"
29
- flist = Dir.glob(default_pattern)
30
- @listb = RubyCurses::Listbox.new @form do
31
- name "mylist"
32
- row 5
33
- col 10
34
- width 40
35
- height 10
36
- list flist
37
- title "File list"
38
- title_attrib 'bold'
39
- end
40
- #@listb.list.bind(:ENTER_ROW) { field.set_buffer @listb.selected_item }
41
- listb = @listb
42
- field.bind(:CHANGE) do |f|
43
- flist = Dir.glob(f.getvalue+"*")
44
- l = listb.list
45
- l.remove_all
46
- l.insert 0, *flist
47
- end
48
- atitle = @dialog_title || "Quick Dirty(TM) File Chooser"
49
- @mb = RubyCurses::MessageBox.new @form do
50
- title atitle
51
- type :override
52
- height 20
53
- width 60
54
- top 5
55
- left 20
56
- default_button 0
57
- button_type :ok_cancel
58
- end
59
- #$log.debug "MBOX :selected #{@listb.selected_item}, #{@listb[@listb.getvalue[0]]} "
60
- return @mb.selected_index == 0 ? :OK : :CANCEL
61
- end
62
- def get_selected_file
63
- #return @mb.selected_index == 0 ? @listb.selected_item : nil
64
- #return @mb.selected_index == 0 ? @listb[@listb.getvalue[0]] : nil
65
- # return either the selected_value or if user pressed okay, then focussed item
66
- return @mb.selected_index == 0 ? @listb.selected_value || @listb.selected_item : nil
67
- end
68
- end
@@ -1,1239 +0,0 @@
1
- #####################################################
2
- # This is a sample program demonstrating a 2 pane file explorer using
3
- # rbcurse's widgets.
4
- # I have used a listbox here, perhaps a Table would be more configurable
5
- # than a listbox.
6
- #
7
- # FIXME many popups use the old Messagebox which will crash. i've updated
8
- # grep not the others.
9
- # Copyright rkumar 2009, 2010 under Ruby License.
10
- #
11
- ####################################################
12
- #require 'rubygems'
13
- #require 'ncurses'
14
- #require 'logger'
15
- require 'rbcurse'
16
- require 'rbcurse/core/widgets/rcombo'
17
- require 'rbcurse/extras/widgets/rlistbox'
18
- require './rfe_renderer'
19
- require 'rbcurse/core/widgets/keylabelprinter'
20
- require 'rbcurse/core/widgets/applicationheader'
21
- require 'rbcurse/core/include/action'
22
- require 'fileutils'
23
- require 'yaml' ## added for 1.9
24
- #$LOAD_PATH << "/Users/rahul/work/projects/rbcurse/"
25
-
26
- # TODO
27
- # operations on selected files: move, delete, zip, copy
28
- # - delete should move to Trash if exists - DONE
29
- # global - don't ask confirm
30
- # Select based on pattern.
31
- # This class represents the finder pane. There are 2
32
- # on this sample app
33
- # NOTE: rfe_renderer uses entries so you may need to sync it with list_data_model
34
- # actually, renderer should refer back to list data model!
35
- class FileExplorer
36
- include FileUtils
37
- attr_reader :wdir
38
- attr_reader :list # listbox
39
- attr_reader :dir
40
- attr_reader :prev_dirs
41
- attr_reader :other_list # the opposite list
42
- attr_reader :entries # avoid, can be outdated
43
- attr_accessor :filter_pattern
44
-
45
- def initialize form, rfe, row, col, height, width
46
- @form = form
47
- @rfe = rfe
48
- @row, @col, @ht, @wid = row, col, height, width
49
- @dir = Dir.new(Dir.getwd)
50
- @wdir = @dir.path
51
- @filter_pattern = '*'
52
- @prev_dirs=[]
53
- @inside_block = false
54
- $entry_count = 0 # just for show... may not be accurate after deletes etc
55
-
56
- end
57
- def title str
58
- @list.title = str
59
- end
60
- def selected_color
61
- @list.selected_color
62
- end
63
- def selected_bgcolor
64
- @list.selected_bgcolor
65
- end
66
-
67
- # changes to given dir
68
- # ensure that path is provided since other list
69
- # may have cd'd elsewhere
70
- def change_dir adir
71
- list = @list
72
- begin
73
- #dir = File.expand_path dir
74
- #cd "#{@dir.path}/#{adir}"
75
- cd adir
76
- list.title = pwd()
77
- @dir = Dir.new(Dir.getwd)
78
- @wdir = @dir.path
79
- @prev_dirs << @wdir
80
- rescan
81
- rescue => err
82
- @rfe.status_row.text = err.to_s
83
- end
84
- end
85
- def goto_previous_dir
86
- #alert "Previous dirs contain #{@prev_dirs} "
87
- d = @prev_dirs.pop
88
- if !d.nil? && d == @wdir
89
- d = @prev_dirs.pop
90
- end
91
- d = @wdir unless d # for those cases where we are showing some result and user doesn't know how t get back
92
- change_dir d unless d.nil?
93
- end
94
- def filter list
95
- list.delete_if { |f|
96
- !File.directory? @wdir +"/"+ f and !File.fnmatch?(@filter_pattern, f)
97
- }
98
- #$log.debug " FILTER CALLED AFTER #{list.size}, #{list.entries}"
99
- end
100
- def rescan
101
- flist = @dir.entries
102
- $entry_count = flist.size # just for show... may not be accurate after deletes etc
103
- flist.shift
104
- #populate @entries
105
- populate flist
106
- end
107
- def populate flist
108
- #fl << format_string("..", nil)
109
- #fl = []
110
- #flist.each {|f| ff = "#{@wdir}/#{f}"; stat = File.stat(ff)
111
- # fl << format_string(f, stat)
112
- #}
113
- filter(flist) if @filter_pattern != '*'
114
- @entries = flist
115
- list.list_data_model.remove_all
116
- #list.list_data_model.insert 0, *fl
117
- list.list_data_model.insert 0, *flist
118
- list.set_form_row
119
- #$entry_count = list.size # just for show... may not be accurate after deletes etc
120
- end
121
- def sort key, reverse=false
122
- # remove parent before sorting, keep at top
123
- first = @entries.delete_at(0) if @entries[0]==".."
124
- key ||= @sort_key
125
- cdir=cur_dir()+"/"
126
- case key
127
- when :size
128
- @entries.sort! {|x,y| xs = File.stat(cdir+x); ys = File.stat(cdir+y);
129
- if reverse
130
- xs.size <=> ys.size
131
- else
132
- ys.size <=> xs.size
133
- end
134
- }
135
- when :mtime
136
- @entries.sort! {|x,y| xs = File.stat(cdir+x); ys = File.stat(cdir+y);
137
- if reverse
138
- xs.mtime <=> ys.mtime
139
- else
140
- ys.mtime <=> xs.mtime
141
- end
142
- }
143
- when :atime
144
- @entries.sort! {|x,y| xs = File.stat(cdir+x); ys = File.stat(cdir+y);
145
- if reverse
146
- xs.atime <=> ys.atime
147
- else
148
- ys.atime <=> xs.atime
149
- end
150
- }
151
- when :name
152
- @entries.sort! {|x,y| x <=> y
153
- if reverse
154
- x <=> y
155
- else
156
- y <=> x
157
- end
158
- }
159
- when :ext
160
- @entries.sort! {|x,y|
161
- if reverse
162
- File.extname(cdir+x) <=> File.extname(cdir+y)
163
- else
164
- File.extname(cdir+y) <=> File.extname(cdir+x)
165
- end
166
- }
167
- end
168
- @sort_key = key
169
- @entries.insert 0, first unless first.nil? # keep parent on top
170
- populate @entries
171
- end
172
- GIGA_SIZE = 1073741824.0
173
- MEGA_SIZE = 1048576.0
174
- KILO_SIZE = 1024.0
175
-
176
- # Return the file size with a readable style.
177
- def readable_file_size(size, precision)
178
- case
179
- #when size == 1 : "1 B"
180
- when size < KILO_SIZE then "%d B" % size
181
- when size < MEGA_SIZE then "%.#{precision}f K" % (size / KILO_SIZE)
182
- when size < GIGA_SIZE then "%.#{precision}f M" % (size / MEGA_SIZE)
183
- else "%.#{precision}f G" % (size / GIGA_SIZE)
184
- end
185
- end
186
- def date_format t
187
- t.strftime "%Y/%m/%d"
188
- end
189
- def oldformat_string fn, stat
190
- max_len = 30
191
- f = fn.dup
192
- if File.directory? f
193
- #"%-*s\t(dir)" % [max_len,f]
194
- #f = "/"+f # disallows search on keypress
195
- f = f + "/ "
196
- end
197
- if f.size > max_len
198
- f = f[0..max_len-1]
199
- end
200
- "%-*s\t%10s\t%s" % [max_len,f, readable_file_size(stat.size,1), date_format(stat.mtime)]
201
- end
202
- def cur_dir
203
- @dir.path
204
- end
205
- alias :current_dir :cur_dir
206
- def draw_screen dir=nil
207
- # I get an error here if dir in yaml file is non-existent, like deleted or copied from another machine
208
- # 2010-08-22 19:25
209
- if dir
210
- if File.exists?(dir) && File.directory?(dir)
211
- cd dir unless dir.nil?
212
- else
213
- dir = nil
214
- end
215
- end
216
-
217
- wdir = FileUtils.pwd
218
- @prev_dirs << wdir
219
- @dir = Dir.new(Dir.getwd)
220
- @wdir = @dir.path
221
- r = @row
222
- c = @col
223
- #cola = 1
224
- #colb = Ncurses.COLS/2
225
- ht = @ht
226
- wid = @wid
227
- #fl = Dir.glob(default_pattern)
228
- #flist << format_string("..", nil)
229
- fl = @dir.entries
230
- fl.shift
231
- filter(fl)
232
- #flist = []
233
- #fl.each {|f| stat = File.stat(f)
234
- # flist << format_string(f, stat)
235
- #}
236
- @entries = fl
237
- $entry_count = @entries.size
238
- title = pwd()
239
- @wdir = title
240
- rfe = self
241
-
242
- lista = Listbox.new @form do
243
- name "lista"
244
- row r
245
- col c
246
- width wid
247
- height ht
248
- #list flist
249
- list fl
250
- title wdir
251
- #title_attrib 'reverse'
252
- cell_renderer RfeRenderer.new "", {"color"=>@color, "bgcolor"=>@bgcolor, "parent" => rfe, "display_length"=> wid-2}
253
- KEY_ROW_SELECTOR 0 # C-space since space used for preview
254
- end
255
- @list = lista
256
- lista.bind(:ENTER) {|l| @rfe.current_list(self); l.title_attrib 'reverse'; }
257
- lista.bind(:LEAVE) {|l| l.title_attrib 'normal'; }
258
-
259
-
260
- #row_cmd = lambda {|list| file = list.list_data_model[list.current_index].split(/\t/)[0].strip; @rfe.status_row.text = File.stat("#{cur_dir()}/#{file}").inspect }
261
- row_cmd = lambda {|lb, list| file = list.entries[lb.current_index]; @rfe.status_row.text = file; # File.stat("#{cur_dir()}/#{file}").inspect
262
- }
263
- lista.bind(:ENTER_ROW, self) {|lb,list| row_cmd.call(lb,list) }
264
-
265
- end
266
- def list_data
267
- @list.list_data_model
268
- end
269
- def current_index
270
- @list.current_index
271
- end
272
- def filename ix=current_index()
273
- #@entries[@list.current_index]
274
- list_data()[ix]
275
- end
276
- def filepath ix=current_index()
277
- f = filename(ix)
278
- return unless f
279
- if f[0,1]=='/'
280
- f
281
- else
282
- cur_dir() + "/" + f
283
- end
284
- end
285
- # delete the item at position i
286
- def delete_at i=@list.current_index
287
- ret = @list.list_data_model.delete_at i
288
- ret = @entries.delete_at i
289
- end
290
- def delete obj
291
- ret = @list.list_data_model.delete obj
292
- ret = @entries.delete_at obj
293
- end
294
- def insert_at obj, ix = @list.current_index
295
- @list.list_data_model.insert ix, f
296
- @entries.insert ix, obj
297
- end
298
- def remove_selected_rows
299
- rows = @list.selected_rows
300
- rows=rows.sort! {|x,y| y <=> x }
301
- rows.each do |i|
302
- ret = @list.list_data_model.delete_at i
303
- ret = @entries.delete_at i
304
- end
305
- end
306
-
307
- # ADD
308
- end
309
- class RFe
310
- attr_reader :status_row
311
- def initialize
312
- @window = VER::Window.root_window
313
- @form = Form.new @window
314
- # made in invisible since i am using chunks to print. however, we do set this variable
315
- status_row = RubyCurses::Label.new @form, {'text' => "", :row => Ncurses.LINES-4, :col => 0, :display_length=>Ncurses.COLS-2, :visible => false}
316
- @status_row = status_row
317
- colb = Ncurses.COLS/2
318
- ht = Ncurses.LINES - 4
319
- wid = Ncurses.COLS/2 - 0
320
- @trash_path = File.expand_path("~/.Trash")
321
- @trash_exists = File.directory? @trash_path
322
- $log.debug " trash_path #{@trash_path}, #{@trash_exists}"
323
- @lista = FileExplorer.new @form, self, row=1, col=1, ht, wid
324
- @listb = FileExplorer.new @form, self, row=1, col=colb, ht, wid
325
-
326
- init_vars
327
- end
328
- def init_vars
329
- @bookmarks=[]
330
- @config_name = File.expand_path("~/.rfe.yml")
331
- if File.exist? @config_name
332
- @config = YAML::load( File.open(@config_name));
333
- if !@config.nil?
334
- @bookmarks = @config["bookmarks"]||[]
335
- @last_dirs = @config["last_dirs"]
336
- end
337
- end
338
- @config ||={}
339
- @stopping = false
340
- end
341
- def save_config
342
- @config["last_dirs"]=[@lista.current_dir(),@listb.current_dir()]
343
- File.open(@config_name, "w") { | f | YAML.dump( @config, f )}
344
- end
345
- def move
346
- fp = @current_list.filepath #.gsub(' ',"\ ")
347
- fn = @current_list.filename
348
- $log.debug " FP #{fp}"
349
- other_list = [@lista, @listb].index(@current_list)==0 ? @listb : @lista
350
- other_dir = other_list.cur_dir
351
- $log.debug " OL #{other_list.cur_dir}"
352
- if @current_list.list.selected_row_count == 0
353
- str= "#{fn}"
354
- else
355
- str= "#{@current_list.list.selected_row_count} files "
356
- end
357
-
358
- mb = RubyCurses::MessageBox.new :width => 80 do
359
- title "Move"
360
- message "Move #{str} to"
361
- add Field.new :default => other_dir, :bgcolor => :cyan, :name => "name"
362
- button_type :ok_cancel
363
- default_button 0
364
- end
365
- index = mb.run
366
- fld = mb.widget("name")
367
-
368
- #mb = RubyCurses::MessageBox.new do
369
- #title "Move"
370
- #message "Move #{str} to"
371
- #type :input
372
- #width 80
373
- #default_value other_dir
374
- #button_type :ok_cancel
375
- #default_button 0
376
- #end
377
- #confirm "selected :#{mb.input_value}, #{mb.selected_index}"
378
- if index == 0
379
- begin
380
- if @current_list.list.selected_row_count == 0
381
- FileUtils.move(fp, fld.text)
382
- #ret = @current_list.list.list().delete_at @current_list.list.current_index # ???
383
- # @current_list.entries.delete_at @current_list.current_index
384
- @current_list.delete_at
385
- else
386
- each_selected_row do |f|
387
- FileUtils.move(f, fld.text)
388
- end
389
- @current_list.remove_selected_rows
390
- @current_list.list.clear_selection
391
- end
392
- rescue => err
393
- textdialog err
394
- $log.debug "XXX: Exception in rfe, move #{err.to_s} "
395
- end
396
- other_list.rescan
397
- end
398
- end
399
- def each_selected_row #title, message, default_value
400
- rows = @current_list.list.selected_rows
401
- rows = rows.dup
402
- rows.each do |i|
403
- fp = @current_list.filepath i
404
- #$log.debug " moving #{i}: #{fp}"
405
- #FileUtils.move(fp, mb.input_value)
406
- yield fp
407
- end
408
- end
409
- def copy
410
- fp = @current_list.filepath #.gsub(' ',"\ ")
411
- fn = @current_list.filename
412
- $log.debug " FP #{fp}"
413
- other_list = [@lista, @listb].index(@current_list)==0 ? @listb : @lista
414
- other_dir = other_list.cur_dir
415
- $log.debug " OL #{other_list.cur_dir}"
416
- if @current_list.list.selected_row_count == 0
417
- str= "#{fn}"
418
- else
419
- str= "#{@current_list.list.selected_row_count} files "
420
- end
421
- mb = RubyCurses::MessageBox.new do
422
- title "Copy"
423
- message "Copy #{str} to"
424
- type :input
425
- width 80
426
- default_value other_dir
427
- button_type :ok_cancel
428
- default_button 0
429
- end
430
- if mb.selected_index == 0
431
- if @current_list.list.selected_row_count == 0
432
- FileUtils.copy(fp, mb.input_value)
433
- else
434
- each_selected_row do |f|
435
- FileUtils.copy(f, mb.input_value)
436
- end
437
- @current_list.list.clear_selection
438
- end
439
- other_list.rescan
440
- end
441
- end
442
- def delete
443
- fp = @current_list.filepath #.gsub(' ',"\ ")
444
- fn = @current_list.filename
445
- if @current_list.list.selected_row_count == 0
446
- str= "#{fn}"
447
- else
448
- str= "#{@current_list.list.selected_row_count} files "
449
- end
450
- if confirm("delete #{str}")
451
- if @current_list.list.selected_row_count == 0
452
- if @trash_exists
453
- FileUtils.mv fp, @trash_path
454
- else
455
- FileUtils.rm fp
456
- end
457
- ret=@current_list.delete_at
458
- else
459
- each_selected_row do |f|
460
- if @trash_exists
461
- FileUtils.mv f, @trash_path
462
- else
463
- FileUtils.rm f
464
- end
465
- end
466
- @current_list.remove_selected_rows
467
- @current_list.list.clear_selection
468
- end
469
- end
470
- end
471
- def copy1
472
- fp = @current_list.filepath
473
- fn = @current_list.filename
474
- $log.debug " FP #{fp}"
475
- other_list = [@lista, @listb].index(@current_list)==0 ? @listb : @lista
476
- other_dir = other_list.cur_dir
477
- $log.debug " OL #{other_list.cur_dir}"
478
- str= "copy #{fn} to #{other_list.cur_dir}"
479
- $log.debug " copy #{fp}"
480
- #confirm "#{str}"
481
- mb = RubyCurses::MessageBox.new do
482
- title "Copy"
483
- message "Copy #{fn} to"
484
- type :input
485
- width 60
486
- default_value other_dir
487
- button_type :ok_cancel
488
- default_button 0
489
- end
490
- #confirm "selected :#{mb.input_value}, #{mb.selected_index}"
491
- if mb.selected_index == 0
492
- # need to redraw directories
493
- FileUtils.copy(fp, mb.input_value)
494
- other_list.rescan
495
- end
496
- end
497
- ## TODO : make this separate and callable with its own keylabels
498
- # Now you can just use viewer() instead of having to write this. See Utils in rwidget.rb
499
- def view content=nil # can throw IO errors
500
- require 'rbcurse/core/widgets/rtextview'
501
- wt = 0
502
- wl = 0
503
- wh = Ncurses.LINES-wt
504
- ww = Ncurses.COLS-wl
505
- if content.nil?
506
- begin
507
- fp = @current_list.filepath
508
- content = get_contents(fp)
509
- rescue => err
510
- $log.debug err.to_s
511
- $log.debug(err.backtrace.join("\n"))
512
- alert err.to_s
513
- return
514
- end
515
- else
516
- fp=""
517
- end
518
- @layout = { :height => wh, :width => ww, :top => wt, :left => wl }
519
- @v_window = VER::Window.new(@layout)
520
- @v_form = RubyCurses::Form.new @v_window
521
- @textview = TextView.new @v_form do
522
- name "myView"
523
- row 0
524
- col 0
525
- width ww
526
- height wh-0
527
- title fp
528
- title_attrib 'bold'
529
- print_footer true
530
- footer_attrib 'bold'
531
- end
532
- #content = File.open(fp,"r").readlines
533
- begin
534
- @textview.set_content content #, :WRAP_WORD
535
- @v_form.repaint
536
- @v_window.wrefresh
537
- Ncurses::Panel.update_panels
538
- while((ch = @v_window.getchar()) != ?\C-q.getbyte(0) )
539
- break if ch == FFI::NCurses::KEY_F3 || ch == KEY_F10 || ch == ?q.getbyte(0)
540
- @v_form.handle_key ch
541
- @v_form.repaint
542
- ##@v_window.wrefresh
543
- end
544
- rescue => err
545
- alert err.to_s
546
- ensure
547
- @v_window.destroy if !@v_window.nil?
548
- end
549
- end
550
- def get_contents fp
551
- return nil unless File.readable? fp
552
- return Dir.new(fp).entries if File.directory? fp
553
- case File.extname(fp)
554
- when '.tgz','.gz'
555
- cmd = "tar -ztvf #{fp}"
556
- content = %x[#{cmd}]
557
- when '.zip'
558
- cmd = "unzip -l #{fp}"
559
- content = %x[#{cmd}]
560
- else
561
- content = File.open(fp,"r").readlines
562
- end
563
- end
564
- def opt_file c
565
- fp = @current_list.filepath
566
- fn = @current_list.filename
567
- other_list = [@lista, @listb].index(@current_list)==0 ? @listb : @lista
568
- case c
569
- when 'c'
570
- copy
571
- when 'm'
572
- move
573
- when 'd'
574
- delete
575
- when 'u'
576
- str= "move #{fn} to #{other_list.cur_dir}"
577
- if confirm("#{str}")
578
- $log.debug " MOVE #{str}"
579
- end
580
- when 'v'
581
- str= "view #{fp}"
582
- #if confirm("#{str}")==:YES
583
- $log.debug " VIEW #{fp}"
584
- view
585
- #end
586
- when 'r'
587
- str= "ruby #{fn}"
588
- if confirm("#{str}")
589
- $log.debug " #{str} "
590
- end
591
- when 'e'
592
- str= "edit #{fp}"
593
- #if confirm("#{str}")==:YES
594
- edit fp
595
- when 'x'
596
- str= "exec #{fp}"
597
- exec_popup fp
598
- when 'p'
599
- page fp
600
- when 'q'
601
- qlmanage fp
602
- end
603
- end
604
- def opt_dir c
605
- fp = @current_list.filepath
606
- fn = @current_list.filename
607
- case c
608
- when 'O'
609
- # str= "copy #{fn} to #{other_list.cur_dir}"
610
- if File.directory? @current_list.filepath
611
- @current_list.change_dir fp
612
- end
613
- when 'o'
614
- if File.directory? @current_list.filepath
615
- @other_list.change_dir fp
616
- end
617
- @open_in_other = true # ???basically keep opening in other
618
- when 'd'
619
- str= "delete #{fn} "
620
- if confirm("#{str}")
621
- $log.debug " delete #{fp}"
622
- FileUtils.rm fp
623
- ret=@current_list.list.list_data_model.delete_at @current_list.list.current_index # ???
624
- $log.debug " DEL RET #{ret},#{@current_list.list.current_index}"
625
- end
626
- when 'u'
627
- str= "move #{fn} to #{other_list.cur_dir}"
628
- if confirm("#{str}")
629
- $log.debug " MOVE #{str}"
630
- end
631
- when 'b'
632
- dd = @current_list.wdir
633
- @bookmarks << dd unless @bookmarks.include? dd
634
- when 'u'
635
- dd = @current_list.wdir
636
- @bookmarks.delete dd
637
- when 'l'
638
- @current_list.populate @bookmarks
639
- when 's'
640
- @config["bookmarks"] = @bookmarks
641
- save_config
642
- when 'e'
643
- str= "edit #{fp}"
644
- #if confirm("#{str}")==:YES
645
- edit fp
646
- when 'm'
647
- f = get_string("Enter a directory to create", 20 )
648
- if f != ""
649
- FileUtils.mkdir f
650
- @current_list.list.list_data_model.insert @current_list.list.current_index, f # ???
651
- @current_list.entries.insert @current_list.list.current_index, f # ???
652
- end
653
-
654
- when 'x'
655
- str= "exec #{fp}"
656
- exec_popup fp
657
- end
658
- end
659
- def exec_popup fp
660
- last_exec_def1 = @last_exec_def1 || ""
661
- last_exec_def2 = @last_exec_def2 || false
662
-
663
- sel, inp, hash = get_string_with_options("Enter a command to execute on #{fp}", 30, last_exec_def1, {"checkboxes" => ["view result"], "checkbox_defaults"=>[last_exec_def2]})
664
- if sel == 0
665
- @last_exec_def1 = inp
666
- @last_exec_def2 = hash["view result"]
667
- cmd = "#{inp} #{fp}"
668
- filestr = %x[ #{cmd} 2>/dev/null ]
669
- if hash["view result"]==true
670
- view filestr
671
- end
672
- end
673
- end
674
- def edit fp=@current_list.filepath
675
- $log.debug " edit #{fp}"
676
- editor = ENV['EDITOR'] || 'vi'
677
- vimp = %x[which #{editor}].chomp
678
- shell_out "#{vimp} #{fp}"
679
- end
680
-
681
- # TODO we need to move these to some common file so differnt programs and demos
682
- # can use them on pressing space or enter.
683
- def page fp=@current_list.filepath
684
- ft=%x[file #{fp}]
685
- if ft.index("text")
686
- pager = ENV['PAGER'] || 'less'
687
- vimp = %x[which #{pager}].chomp
688
- shell_out "#{vimp} #{fp}"
689
- elsif ft.index(/zip/i)
690
- shell_out "tar tvf #{fp} | less"
691
- elsif ft.index(/directory/i)
692
- shell_out "ls -lh #{fp} | less"
693
- else
694
- alert "#{fp} is not text, not paging "
695
- #use_on_file "als", fp # only zip or archive
696
- end
697
- end
698
- def qlmanage fp=@current_list.filepath
699
- begin
700
- a=%x[which qlmanage]
701
- if a != ""
702
- cmd="qlmanage -p #{@current_list.filepath} 2>/dev/null"
703
- %x[#{cmd}]
704
- else
705
- alert "qlmanage not present on your system. Trying pager"
706
- page fp
707
- end
708
- rescue Interrupt
709
- rescue => err
710
- alert err.to_s
711
- end
712
- end
713
- # also if calling program gives output but does not stop
714
- # or take control, then nothing will show up
715
- def use_on_file prog, args, fp=@current_list.filepath
716
- vimp = %x[which #{prog}].chomp
717
- if vimp != ""
718
- alert "using #{prog} "
719
- shell_out "#{vimp} #{args } #{fp}"
720
- else
721
- alert "could not locate #{prog} "
722
- end
723
- end
724
- def stopping?
725
- @stopping
726
- end
727
- def draw_screens
728
- lasta = lastb = nil
729
- if !@config["last_dirs"].nil?
730
- lasta = @config["last_dirs"][0]
731
- lastb = @config["last_dirs"][1]
732
- end
733
- @lista.draw_screen lasta
734
- @listb.draw_screen lastb
735
-
736
- # bind dd to delete file
737
- # actually this should be in listbox, and we should listen for row delete and then call opt_file
738
- @form.bind_key([?d,?d], 'delete'){
739
- opt_file 'd'
740
- }
741
- # list traps 'q' so this won't work
742
- @form.bind_key([?q,?q], 'quit'){
743
- @stopping = true
744
- }
745
- # this won't work since the listbox will consume the d first
746
- @form.bind_key(?@, 'home'){
747
- @current_list.change_dir File.expand_path("~/")
748
- }
749
- @form.bind_key(?^, 'previous dir'){
750
- @current_list.change_dir @current_list.prev_dirs[0] unless @current_list.prev_dirs.empty?
751
- }
752
- @form.bind_key(?\C-f, 'file menu'){
753
- @klp.mode :file
754
- @klp.repaint
755
- while((ch = @window.getchar()) != ?\C-c.getbyte(0) )
756
- if ch < 33 || ch > 126
757
- Ncurses.beep
758
- elsif "cmdsuvrexpq".index(ch.chr) == nil
759
- Ncurses.beep
760
- else
761
- opt_file ch.chr
762
- break
763
- end
764
- end
765
- @klp.mode :normal
766
- }
767
- # C-d has been bound to scroll-down
768
- @form.bind_key(?\C-w, 'dir menu'){
769
- @klp.mode :dir
770
- @klp.repaint
771
- keys = @klp.get_current_keys
772
- while((ch = @window.getchar()) != ?\C-c.getbyte(0) )
773
- if ch < 33 || ch > 126
774
- Ncurses.beep
775
- elsif !keys.include?(ch.chr)
776
- Ncurses.beep
777
- else
778
- opt_dir ch.chr
779
- break
780
- end
781
- end
782
- @klp.mode :normal
783
- }
784
- # backspace KEY_BS
785
- @form.bind_key(127, 'previous dir'){
786
- @current_list.goto_previous_dir
787
- }
788
- # form gives this to list which consumes it for selection.
789
- # need to bind to list's LIST_SELECTION_EVENT
790
- @form.bind_key(32, 'pager'){
791
- fp = @current_list.filepath
792
- page fp
793
- }
794
- @form.bind_key(FFI::NCurses::KEY_F3, 'view'){
795
- begin
796
- view()
797
- rescue => err
798
- alert err.to_s
799
- end
800
- }
801
- @form.bind_key(FFI::NCurses::KEY_F1, 'help'){
802
- #Io.view(["this is some help text","hello there"])
803
- color0 = get_color($promptcolor, 'black','green')
804
- color1 = get_color($reversecolor, 'green','black')
805
- color2 = get_color($reversecolor, 'magenta','black')
806
- arr = []
807
- #arr << " FILE BROWSER HELP "
808
- arr << [color0," FILE BROWSER HELP ", FFI::NCurses::A_NORMAL]
809
- arr << " "
810
- arr << [[color1," <tab> ",nil],[color2, "- switch between windows", nil]]
811
- arr << [[color1," <enter> ",nil],[color2, "- open dir", nil]]
812
- arr << [[color1," F3 ",nil],[color2, "- view file/dir/zip contents (toggle) ", nil]]
813
- arr << [[color1," F4 ",nil],[color2, "- edit file content", nil]]
814
- arr << [[color1," <char> ", nil],[color2, "first file starting with <char>",nil]]
815
- #arr << " VIM MODE "
816
- arr << [color0," VIM MODE ", FFI::NCurses::A_NORMAL]
817
- arr << [[color1," M",nil],[color2, "-v - Vim like bindings for navigation (toggle)", nil]]
818
- arr << " jk gg G up down motion, C-n C-p, Alt-0, Alt-9 "
819
- arr << [[color1," p or Space ",nil],[color2, "- use pager on current file", nil]]
820
- arr << [[color1," q ",nil],[color2, "- use qlmanage on file ",nil],[$promptcolor, " (OSX)", nil]]
821
- arr << [[color1," f<char> ",nil],[color2, "- first file starting with <char>", nil]]
822
-
823
- arr << " "
824
- arr << " < > ^ V - move help window "
825
- arr << " "
826
- # next line does not work due to chunks
827
- w = arr.max_by(&:length).length
828
- #arr = ["this is some help text","hello there"]
829
-
830
- require 'rbcurse/core/util/viewer'
831
- RubyCurses::Viewer.view(arr, :layout => [10,10, 4+arr.size, w+2],:close_key => KEY_RETURN, :title => "<Enter> to close", :print_footer => false) do |t|
832
- # you may configure textview further here.
833
- #t.suppress_borders true
834
- #t.color = :black
835
- #t.bgcolor = :white
836
- # or
837
- #t.attr = :reverse
838
- t.attr = :normal
839
- #t.bind_key(KEY_F1){ alert "closing up!"; throw :close }
840
- # just for kicks move window around
841
- t.bind_key('<'){ f = t.form.window; c = f.left - 1; f.hide; f.mvwin(f.top, c); f.show;
842
- f.reset_layout([f.height, f.width, f.top, c]);
843
- }
844
- t.bind_key('>'){ f = t.form.window; c = f.left + 1; f.hide; f.mvwin(f.top, c);
845
- f.reset_layout([f.height, f.width, f.top, c]); f.show;
846
- }
847
- t.bind_key('^'){ f = t.form.window; c = f.top - 1 ; f.hide; f.mvwin(c, f.left);
848
- f.reset_layout([f.height, f.width, c, f.left]) ; f.show;
849
- }
850
- t.bind_key('V'){ f = t.form.window; c = f.top + 1 ; f.hide; f.mvwin(c, f.left);
851
- f.reset_layout([f.height, f.width, c, f.left]); f.show;
852
- }
853
- end
854
- }
855
- @form.bind_key(FFI::NCurses::KEY_F4, 'edit'){
856
- edit()
857
- }
858
- @form.bind_key(FFI::NCurses::KEY_F6, 'sort'){
859
- selected_index, sort_key, reverse, case_sensitive = sort_popup
860
- if selected_index == 0
861
- @current_list.sort(sort_key, reverse)
862
- end
863
- }
864
- @form.bind_key(FFI::NCurses::KEY_F5, 'filter'){
865
- filter()
866
- }
867
- @form.bind_key(FFI::NCurses::KEY_F7, 'grep'){
868
- grep_popup()
869
- }
870
- @form.bind_key(FFI::NCurses::KEY_F8, 'system'){
871
- system_popup()
872
- }
873
- # will work if you are in vim mode
874
- @form.bind_key(?p, 'pager'){
875
- page
876
- }
877
- @form.bind_key(?z, 'qlmanage OSX'){
878
- qlmanage
879
- }
880
- # will no longer come here. list event has to be used
881
- #@form.bind_key(?\C-m){ # listbox has eaten it up
882
- @lista.list.bind(:PRESS){
883
- dir = @current_list.filepath
884
- if File.directory? @current_list.filepath
885
- @current_list.change_dir dir
886
- end
887
- }
888
- @listb.list.bind(:PRESS){
889
- dir = @current_list.filepath
890
- if File.directory? @current_list.filepath
891
- @current_list.change_dir dir
892
- end
893
- }
894
- gw = get_color($reversecolor, 'green', 'black')
895
- bw = get_color($datacolor, 'blue', 'black')
896
- @klp = RubyCurses::KeyLabelPrinter.new @form, get_key_labels
897
- @klp.footer_color_pair = bw
898
- @klp.footer_mnemonic_color_pair = gw
899
- @klp.set_key_labels get_key_labels(:file), :file
900
- @klp.set_key_labels get_key_labels(:view), :view
901
- @klp.set_key_labels get_key_labels(:dir), :dir
902
- @form.repaint
903
- @window.wrefresh
904
- Ncurses::Panel.update_panels
905
- begin
906
- chunks=["File","Key"]
907
- color0 = get_color($promptcolor, 'white','blue')
908
- color1 = get_color($datacolor, 'black','green')
909
-
910
- ## qq stops program, but only if M-v (vim mode)
911
- while(!stopping? && (ch = @window.getchar()) != ?\C-q.getbyte(0) )
912
- break if ch == KEY_F10
913
- s = keycode_tos ch
914
- #status_row.text = "| Pressed #{ch} , #{s}"
915
- @form.handle_key(ch)
916
-
917
- # the following is just a test of show_colored_chunks
918
- # Please use status_line introduced in 1.4.x
919
- #count = @current_list.list.size
920
- count1 = @lista.list.size
921
- count2 = @listb.list.size
922
- x, y = FFI::NCurses::getyx @window.get_window
923
- chunks[0]=[color0, "%-30s" % status_row.text, FFI::NCurses::A_BOLD]
924
- chunks[1]=[color1, "%-18s" % " | #{ch}, #{s} |", FFI::NCurses::A_NORMAL]
925
- chunks[2]=[color0, " Total: #{count1}, #{count2}"]
926
- @window.wmove(Ncurses.LINES-3,0)
927
- @window.color_set(color0, nil)
928
- @window.print_empty_line
929
- @window.wmove(Ncurses.LINES-3,0)
930
- @window.show_colored_chunks chunks
931
- @window.wmove(x,y)
932
-
933
- #@form.repaint
934
- @window.wrefresh
935
- end
936
- ensure
937
- @window.destroy if !@window.nil?
938
- save_config
939
- end
940
-
941
- end
942
- # TODO
943
- #
944
- #
945
- #
946
-
947
- # current_list
948
- ##
949
- # getter and setter for current_list
950
- def current_list(*val)
951
- if val.empty?
952
- @current_list
953
- else
954
- @current_list = val[0]
955
- @other_list = [@lista, @listb].index(@current_list)==0 ? @listb : @lista
956
- end
957
- end
958
- def get_key_labels categ=nil
959
- if categ.nil?
960
- key_labels = [
961
- ['C-q', 'Exit'], ['C-v', 'View'],
962
- ['C-f', 'File'], ['C-w', 'Dir'],
963
- ['C-Sp','Select'], ['Spc', "Preview"],
964
- ['F3', 'View'], ['F4', 'Edit'],
965
- ['F5', 'Filter'], ['F6', 'Sort'],
966
- ['F7', 'Grep'], ['F8', 'System'],
967
- ['M-0', 'Top'], ['M-9', 'End'],
968
- ['C-p', 'PgUp'], ['C-n', 'PgDn'],
969
- ['M-v', 'Vim Mode'], ['BSpc', 'PrevDir']
970
- ]
971
- elsif categ == :file
972
- key_labels = [
973
- ['c', 'Copy'], ['m', 'Move'],
974
- ['d', 'Delete'], ['v', 'View'],
975
- ['s', 'Select'], ['u', 'Unselect'],
976
- ['p', 'Page'], ['x', 'Exec Cmd'],
977
- ['r', 'ruby'], ['e', "Edit"],
978
- ['C-c', 'Cancel']
979
- ]
980
- elsif categ == :view
981
- key_labels = [
982
- ['c', 'Date'], ['m', 'Size'],
983
- ['d', 'Delete'], ['v', 'View'],
984
- ['C-c', 'Cancel']
985
- ]
986
- elsif categ == :dir
987
- key_labels = [
988
- ['o', 'open'], ['O', 'Open in right'],
989
- ['d', 'Delete'], ['R', 'Del Recurse'],
990
- ['t', 'tree'], ['p', 'Previous'],
991
- ['b', 'Bookmark'], ['u', 'Unbookmark'],
992
- ['l', 'List'], ['s', 'Save'],
993
- ['m', 'mkdir'], nil,
994
- ['C-c', 'Cancel']
995
- ]
996
- end
997
- return key_labels
998
- end
999
- def get_key_labels_table
1000
- key_labels = [
1001
- ['M-n','NewRow'], ['M-d','DelRow'],
1002
- ['C-x','Select'], nil,
1003
- ['M-0', 'Top'], ['M-9', 'End'],
1004
- ['C-p', 'PgUp'], ['C-n', 'PgDn'],
1005
- ['M-Tab','Nxt Fld'], ['Tab','Nxt Col'],
1006
- ['+','Widen'], ['-','Narrow']
1007
- ]
1008
- return key_labels
1009
- end
1010
- def sort_popup
1011
- #mform = RubyCurses::Form.new nil
1012
- mform = nil
1013
- field_list = []
1014
- r = 4
1015
- $radio = RubyCurses::Variable.new
1016
- rtextvalue = [:name, :ext, :size, :mtime, :atime]
1017
- ["Name", "Extension", "Size", "Modify Time", "Access Time" ].each_with_index do |rtext,ix|
1018
- field = RubyCurses::RadioButton.new mform do
1019
- variable $radio
1020
- text rtext
1021
- value rtextvalue[ix]
1022
- color 'black'
1023
- bgcolor 'white'
1024
- #row r
1025
- #col 5
1026
- end
1027
- field_list << field
1028
- r += 1
1029
- end
1030
- r = 4
1031
- ["Reverse", "case sensitive"].each do |cbtext|
1032
- field = RubyCurses::CheckBox.new mform do
1033
- text cbtext
1034
- name cbtext
1035
- color 'black'
1036
- bgcolor 'white'
1037
- #row r
1038
- #col 30
1039
- end
1040
- field_list << field
1041
- r += 1
1042
- end
1043
- mb = RubyCurses::MessageBox.new :width => 50 do
1044
- title "Sort Options"
1045
- button_type :ok_cancel
1046
- default_button 0
1047
- end
1048
- field_list.each { |e| mb.add(e) }
1049
- index = mb.run
1050
- if index == 0
1051
- $log.debug " SORT POPUP #{$radio.value}"
1052
- #$log.debug " SORT POPUP #{mb.inspect}"
1053
- $log.debug " SORT POPUP #{mb.widget("Reverse").value}"
1054
- $log.debug " SORT POPUP #{mb.widget("case sensitive").value}"
1055
- end
1056
- return index, $radio.value, mb.widget("Reverse").value, mb.widget("case sensitive").value
1057
- end
1058
- def filter
1059
- f = get_string("Enter a filter pattern", :maxlen => 20, :default => "*")
1060
- f = "*" if f.nil? or f == ""
1061
- @current_list.filter_pattern = f
1062
- @current_list.rescan
1063
- end
1064
-
1065
- # ask user for pattern to grep through files
1066
- # and display file names in same list
1067
- # Please see testmessagebox.rb for cleaner ways of creating messageboxes.
1068
-
1069
- def grep_popup
1070
- last_regex = @last_regex || ""
1071
- last_pattern = @last_pattern || "*"
1072
- r = 4
1073
- mform = nil
1074
- field = RubyCurses::Field.new mform do
1075
- name "regex"
1076
- #row r
1077
- #col 30
1078
- set_buffer last_regex
1079
- label 'Regex'
1080
- #set_label Label.new @form, {'text' => 'Regex', 'col'=>5, 'mnemonic'=> 'R'}
1081
- end
1082
- r += 1
1083
- field1 = RubyCurses::Field.new mform do
1084
- name "filepattern"
1085
- #row r
1086
- #col 30
1087
- set_buffer last_pattern
1088
- label 'File Pattern'
1089
- #set_label Label.new @form, {'text' => 'File Pattern','col'=>5, :color=>'black',:bgcolor=>'white','mnemonic'=> 'F'}
1090
- end
1091
- r += 1
1092
- fields = []
1093
- ["Recurse", "case insensitive"].each do |cbtext|
1094
- fields.push(RubyCurses::CheckBox.new(mform) do
1095
- text cbtext
1096
- name cbtext
1097
- #color 'black'
1098
- #bgcolor 'white'
1099
- #row r
1100
- #col 5
1101
- end
1102
- )
1103
- r += 1
1104
- end
1105
- mb = RubyCurses::MessageBox.new :width => 50 do
1106
- title "Grep Options"
1107
- button_type :ok_cancel
1108
- default_button 0
1109
- item field
1110
- item field1
1111
- item fields.first
1112
- item fields.last
1113
- end
1114
- selected_index = mb.run
1115
- if selected_index == 0
1116
- return if mb.form.by_name["regex"].getvalue()==""
1117
- @last_regex = mb.form.by_name["regex"].getvalue
1118
- inp = mb.form.by_name["regex"].getvalue
1119
- fp = mb.form.by_name["filepattern"].getvalue
1120
- @last_pattern = fp
1121
- flags=""
1122
- #flags << " -i " if mb.form.by_name["case insensitive"].value==true
1123
- #flags << " -R " if mb.form.by_name["Recurse"].value==true
1124
- flags << " -i " if fields[0].value==true
1125
- flags << " -R " if fields[1].value==true
1126
- # sometimes grep pukes "No such file or directory if you specify some
1127
- # filespec that is not present. I don't want it to come in filestr
1128
- # so i am not piping stderr to stdout
1129
- cmd = "cd #{@current_list.cur_dir()};grep -l #{flags} #{inp} #{fp}"
1130
- filestr = %x[ #{cmd} ]
1131
- files = nil
1132
- files = filestr.split(/\n/) unless filestr.nil?
1133
- #view filestr
1134
- if !files || files.empty?
1135
- alert "Sorry! No files for regex #{inp}"
1136
- return
1137
- end
1138
- @current_list.title "grep #{inp}"
1139
- @current_list.populate files
1140
- # Use backspace to go back
1141
- end
1142
- return selected_index, mb.form.by_name["regex"].getvalue, mb.form.by_name["filepattern"].getvalue, fields[1].value, fields[0].value
1143
- end
1144
-
1145
- def system_popup
1146
- deflt = @last_system || ""
1147
- options=["run in shell","view output","file explorer"]
1148
- #inp = get_string("Enter a system command", 30, deflt)
1149
-
1150
- mb = MessageBox.new :title => "System Command" , :width => 80 do
1151
- add Field.new :label => 'Enter command', :name => "cmd", :display_length => 50, :bgcolor => :cyan,
1152
- :text => deflt
1153
- $radio = RubyCurses::Variable.new
1154
- add RadioButton.new :text => "run in shell", :color => :blue, :variable => $radio
1155
- add RadioButton.new :text => "view output", :color => :red, :variable => $radio
1156
- add RadioButton.new :text => "file explorer", :color => :red, :variable => $radio
1157
- button_type :ok_cancel
1158
- end
1159
- sel = mb.run
1160
- inp = mb.widget("cmd").text
1161
- $log.debug "XXX: value of radio is #{$radio.value}, inp : #{inp} "
1162
- #sel, inp, hash = get_string_with_options("Enter a system command", 40, deflt, {"radiobuttons" => options, "radio_default"=>@last_system_radio || options[0]})
1163
- if sel == 0
1164
- if !inp.nil?
1165
- @last_system = inp
1166
- @last_system_radio = $radio.value
1167
- case $radio.value
1168
- when options[0]
1169
- shell_out inp
1170
- when options[1]
1171
- filestr = %x[ #{inp} ]
1172
- view filestr
1173
- when options[2]
1174
- filestr = %x[ #{inp} ]
1175
- files = nil
1176
- files = filestr.split(/\n/) unless filestr.nil?
1177
- @current_list.title inp
1178
- @current_list.populate files
1179
- $log.debug " SYSTEM got #{files.size}, #{files.inspect}"
1180
- else
1181
- shell_out inp
1182
- end
1183
- end
1184
- end
1185
- end
1186
- # This will notwork, dunno if its being called
1187
- def popup
1188
- deflt = @last_regexp || ""
1189
- #sel, inp, hash = get_string_with_options("Enter a filter pattern", 20, "*", {"checkboxes" => ["case sensitive","reverse"], "checkbox_defaults"=>[true, false]})
1190
- sel, inp, hash = get_string_with_options("Enter a grep pattern", 20, deflt, {"checkboxes" => ["case insensitive","not-including"]})
1191
- if sel == 0
1192
- @last_regexp = inp
1193
- flags=""
1194
- flags << " -i " if hash["case insensitive"]==true
1195
- flags << " -v " if hash["not-including"]==true
1196
- cmd = "grep -l #{flags} #{inp} *"
1197
- filestr = %x[ #{cmd} ]
1198
- files = nil
1199
- files = filestr.split(/\n/) unless filestr.nil?
1200
- view filestr
1201
- end
1202
- $log.debug " POPUP: #{sel}: #{inp}, #{hash['case sensitive']}, #{hash['reverse']}"
1203
- end
1204
- # This won't work if you do something like 'ls -l', you will need to do 'ls -l | less'
1205
- def shell_out command
1206
- @window.hide
1207
- Ncurses.endwin
1208
- ret = system command
1209
- Ncurses.refresh
1210
- #Ncurses.curs_set 0 # why ?
1211
- @window.show
1212
- ret
1213
- end
1214
- end
1215
- if $0 == __FILE__
1216
- include RubyCurses
1217
- include RubyCurses::Utils
1218
-
1219
- begin
1220
- # Initialize curses
1221
- VER::start_ncurses # this is initializing colors via ColorMap.setup
1222
- #$log = Logger.new("rbc13.log")
1223
- $log = Logger.new(ENV['LOGDIR'] || "" + "rbc13.log")
1224
-
1225
- $log.level = Logger::DEBUG
1226
-
1227
- catch(:close) do
1228
- t = RFe.new
1229
- t.draw_screens
1230
- end
1231
- rescue => ex
1232
- ensure
1233
- VER::stop_ncurses
1234
- p ex if ex
1235
- p(ex.backtrace.join("\n")) if ex
1236
- $log.debug( ex) if ex
1237
- $log.debug(ex.backtrace.join("\n")) if ex
1238
- end
1239
- end