rbcurse 1.5.0 → 1.5.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (104) hide show
  1. data/Makefile +21 -0
  2. data/Manifest.txt +6 -0
  3. data/README.markdown +6 -4
  4. data/TODO +372 -0
  5. data/TODO2.txt +121 -0
  6. data/VERSION +1 -1
  7. data/examples/README.txt +67 -0
  8. data/examples/abasiclist.rb +33 -0
  9. data/examples/alpmenu.rb +42 -0
  10. data/examples/app.rb +859 -0
  11. data/examples/app.sample +17 -0
  12. data/examples/appdirtree.rb +74 -0
  13. data/examples/appemail.rb +191 -0
  14. data/examples/appemaillb.rb +308 -0
  15. data/examples/appgcompose.rb +315 -0
  16. data/examples/atree.rb +64 -0
  17. data/examples/common/file.rb +40 -0
  18. data/examples/common/rmail.rb +257 -0
  19. data/examples/data.txt +683 -0
  20. data/examples/data/README.markdown +9 -0
  21. data/examples/data/brew.txt +38 -0
  22. data/examples/data/color.2 +37 -0
  23. data/examples/data/gemlist.txt +60 -0
  24. data/examples/data/lotr.txt +12 -0
  25. data/examples/data/ports.txt +136 -0
  26. data/examples/data/tasks.txt +27 -0
  27. data/examples/data/todocsv.csv +28 -0
  28. data/examples/data/unix1.txt +21 -0
  29. data/examples/data/unix2.txt +11 -0
  30. data/examples/dbdemo.rb +495 -0
  31. data/examples/deprecated/appgmail.rb +952 -0
  32. data/examples/deprecated/splitp.rb +56 -0
  33. data/examples/deprecated/testscrolllb.rb +86 -0
  34. data/examples/deprecated/testscrollp.rb +88 -0
  35. data/examples/deprecated/testscrollta.rb +80 -0
  36. data/examples/deprecated/testscrolltable.rb +165 -0
  37. data/examples/deprecated/testsplit.rb +87 -0
  38. data/examples/deprecated/testsplit2.rb +123 -0
  39. data/examples/deprecated/testsplit3.rb +215 -0
  40. data/examples/deprecated/testsplit3_1.rb +244 -0
  41. data/examples/deprecated/testsplit3a.rb +215 -0
  42. data/examples/deprecated/testsplit3b.rb +237 -0
  43. data/examples/deprecated/testsplitta.rb +148 -0
  44. data/examples/deprecated/testsplittv.rb +142 -0
  45. data/examples/deprecated/testsplittvv.rb +144 -0
  46. data/examples/deprecated/testtpane.rb +215 -0
  47. data/examples/deprecated/testtpane2.rb +145 -0
  48. data/examples/deprecated/testtpanetable.rb +203 -0
  49. data/examples/dirtree.rb +88 -0
  50. data/examples/experimental/resultsetdemo.rb +280 -0
  51. data/examples/experimental/testmform.rb +35 -0
  52. data/examples/experimental/testscroller.rb +117 -0
  53. data/examples/experimental/teststackflow.rb +111 -0
  54. data/examples/menu1.rb +112 -0
  55. data/examples/multispl.rb +86 -0
  56. data/examples/newmessagebox.rb +131 -0
  57. data/examples/newtabbedwindow.rb +100 -0
  58. data/examples/newtesttabp.rb +121 -0
  59. data/examples/qdfilechooser.rb +68 -0
  60. data/examples/rfe.rb +1239 -0
  61. data/examples/rfe_renderer.rb +121 -0
  62. data/examples/sqlc.rb +454 -0
  63. data/examples/sqlm.rb +437 -0
  64. data/examples/sqlt.rb +408 -0
  65. data/examples/status.txt +68 -0
  66. data/examples/table1.rb +24 -0
  67. data/examples/term2.rb +84 -0
  68. data/examples/test1.rb +239 -0
  69. data/examples/test2.rb +674 -0
  70. data/examples/testapp.rb +44 -0
  71. data/examples/testapp2.rb +58 -0
  72. data/examples/testchars.rb +137 -0
  73. data/examples/testcombo.rb +91 -0
  74. data/examples/testkeypress.rb +66 -0
  75. data/examples/testlistbox.rb +113 -0
  76. data/examples/testmenu.rb +101 -0
  77. data/examples/testmulticomp.rb +70 -0
  78. data/examples/testmulticontainer.rb +94 -0
  79. data/examples/testmultispl.rb +199 -0
  80. data/examples/testree.rb +106 -0
  81. data/examples/testtable.rb +264 -0
  82. data/examples/testtabp.rb +107 -0
  83. data/examples/testtodo.rb +584 -0
  84. data/examples/testvimsplit.rb +112 -0
  85. data/examples/testwsshortcuts.rb +64 -0
  86. data/examples/testwsshortcuts2.rb +126 -0
  87. data/examples/todo.db +0 -0
  88. data/examples/todo.yml +191 -0
  89. data/examples/viewtodo.rb +574 -0
  90. data/lib/rbcurse/deprecated/README.markdown +12 -0
  91. data/lib/rbcurse/deprecated/rpad.rb +375 -0
  92. data/lib/rbcurse/deprecated/rscrollpane.rb +512 -0
  93. data/lib/rbcurse/deprecated/rsplitpane.rb +894 -0
  94. data/lib/rbcurse/deprecated/rsplitpane2.rb +1009 -0
  95. data/lib/rbcurse/deprecated/rviewport.rb +204 -0
  96. data/lib/rbcurse/deprecated/widgets/mapper.rb +130 -0
  97. data/lib/rbcurse/deprecated/widgets/rmessagebox.rb +348 -0
  98. data/lib/rbcurse/deprecated/widgets/rtabbedpane.rb +1158 -0
  99. data/lib/rbcurse/deprecated/widgets/rtabbedwindow.rb +167 -0
  100. data/lib/rbcurse/deprecated/widgets/scrollable.rb +301 -0
  101. data/lib/rbcurse/deprecated/widgets/stdscrwindow.rb +309 -0
  102. data/lib/ver/keyboard2.rb +170 -0
  103. data/test/test_rbcurse.rb +0 -0
  104. metadata +131 -9
@@ -0,0 +1,145 @@
1
+ #*******************************************************#
2
+ # testtpane2.rb #
3
+ # written by Rahul Kumar #
4
+ # February 1, 2010 #
5
+ # #
6
+ # testing tabbedpane with textarea, view, listbox #
7
+ # Differs from testtpane added scrollpanes outside view #
8
+ # #
9
+ # Released under ruby license. See #
10
+ # http://www.ruby-lang.org/en/LICENSE.txt #
11
+ # Copyright 2010, Rahul Kumar #
12
+ #*******************************************************#
13
+
14
+ # this is a test program, tests out tabbed panes. type F1 to exit
15
+ #
16
+ #$LOAD_PATH << "/Users/rahul/work/projects/rbcurse/"
17
+ require 'rubygems'
18
+ #require 'ncurses' # FFI
19
+ require 'logger'
20
+ require 'rbcurse'
21
+ require 'rbcurse/rtabbedpane'
22
+ require 'rbcurse/core/widgets/rtextview'
23
+ require 'rbcurse/core/widgets/rtextarea'
24
+ require 'rbcurse/rscrollpane'
25
+
26
+ class TestTabbedPane
27
+ def initialize
28
+ acolor = $reversecolor
29
+ end
30
+ def run
31
+ $config_hash ||= Variable.new Hash.new
32
+ @window = VER::Window.root_window
33
+ @form = Form.new @window
34
+ @form.name = "MAINFORM"
35
+ $log.debug " MAIN FORM #{@form} , #{@window} "
36
+ r = 3; c = 5;
37
+ h = 20; w = 70
38
+ @tp = RubyCurses::TabbedPane.new @form do
39
+ height h
40
+ width w
41
+ row r #5
42
+ col c #8
43
+ #button_type :ok
44
+ end
45
+ sr = 4
46
+ sc = 2
47
+ @scroll = ScrollPane.new nil do
48
+ name "myScroller"
49
+ # row 4 #+ht+1
50
+ # col 0
51
+ # width w-1
52
+ # height h-4
53
+ end
54
+ textview = TextView.new do
55
+ name "myView"
56
+ row 0 #sr+1 # 4
57
+ col 0 #sc+1 # 2
58
+ width w-0
59
+ # height h+10
60
+ title "README.mrku"
61
+ title_attrib 'bold'
62
+ print_footer true
63
+ footer_attrib 'bold'
64
+ end
65
+ content = File.open("../README.markdown","r").readlines
66
+ textview.set_content content #, :WRAP_WORD
67
+ #textview.show_caret = true
68
+ $log.debug " before adding tab to TP "
69
+ @tab1 = @tp.add_tab "&TextView", @scroll
70
+ @scroll.child(textview)
71
+
72
+
73
+ @tab2 = @tp.add_tab "&Settings"
74
+
75
+ #f2 = @tab2.form
76
+ #$log.debug " textarea tp form #{f2} "
77
+ r = 4
78
+ texta = TextArea.new do
79
+ name "myText"
80
+ #row r
81
+ #col 1
82
+ #width w-5
83
+ #height h-5
84
+ title "EditMe.txt"
85
+ title_attrib 'bold'
86
+ print_footer true
87
+ footer_attrib 'bold'
88
+ end
89
+ @tab2.component = texta
90
+ texta << "I expect to pass through this world but once." << "Any good therefore that I can do, or any kindness or abilities that I can show to any fellow creature, let me do it now."
91
+ texta << "Let me not defer it or neglect it, for I shall not pass this way again."
92
+ texta << " "
93
+ texta << "q to exit."
94
+ texta << "Some more text going below scrollpane.. "
95
+ texta << "Love all creatures for they are none but yourself."
96
+ #texta.show_caret = true # since the cursor is not showing correctly, show internal one.
97
+
98
+ # This uses the old style, we get a padded form and then add objects to it.
99
+ @tab3 = @tp.add_tab "&Editors"
100
+ #f3 = @tab3.form
101
+ f3 = @tp.form @tab3 # this replaces previous line, since we don't create form by default
102
+ butts = %w[ &Vim E&macs &Jed E&lvis ]
103
+ bcodes = %w[ VIM EMACS JED ELVIS]
104
+ row = 4
105
+ butts.each_with_index do |name, i|
106
+ RubyCurses::CheckBox.new f3 do
107
+ text name
108
+ variable $config_hash
109
+ name bcodes[i]
110
+ row row+i
111
+ col 5
112
+ end
113
+ end
114
+ @help = "F1 to quit. M- T/S/E for tabs. M-n p h l scrollpane #{$0} Check logger too"
115
+ RubyCurses::Label.new @form, {'text' => @help, "row" => r+h+2, "col" => 2, "color" => "yellow"}
116
+ @form.repaint
117
+ @window.wrefresh
118
+ Ncurses::Panel.update_panels
119
+ while((ch = @window.getchar()) != KEY_F1 )
120
+ # @tp.repaint
121
+ @form.handle_key(ch)
122
+ @window.wrefresh
123
+ end
124
+ #@tp.show
125
+ #@tp.handle_keys
126
+ end
127
+ end
128
+ if $0 == __FILE__
129
+ # Initialize curses
130
+ begin
131
+ # XXX update with new color and kb
132
+ VER::start_ncurses # this is initializing colors via ColorMap.setup
133
+ $log = Logger.new((File.join(ENV["LOGDIR"] || "./" ,"rbc13.log")))
134
+ $log.level = Logger::DEBUG
135
+ n = TestTabbedPane.new
136
+ n.run
137
+ rescue => ex
138
+ ensure
139
+ VER::stop_ncurses
140
+ p ex if ex
141
+ p(ex.backtrace.join("\n")) if ex
142
+ $log.debug( ex) if ex
143
+ $log.debug(ex.backtrace.join("\n")) if ex
144
+ end
145
+ end
@@ -0,0 +1,203 @@
1
+ #*******************************************************#
2
+ # testtpanetable.rb #
3
+ # written by Rahul Kumar #
4
+ # January 29, 2010 #
5
+ # #
6
+ # testing tabbedpane with table #
7
+ # #
8
+ # Released under ruby license. See #
9
+ # http://www.ruby-lang.org/en/LICENSE.txt #
10
+ # Copyright 2010, Rahul Kumar #
11
+ #*******************************************************#
12
+
13
+ # this is a test program, tests out tabbed panes. type F1 to exit
14
+ # Avoid using ScrollPane at present, I intend rewriting it some day
15
+ # It sucks. Even the TabbedPane code will be rewritten completely.
16
+ # Don't use this demo.
17
+ require 'rubygems'
18
+ #require 'ncurses' # FFI
19
+ require 'logger'
20
+ require 'rbcurse'
21
+ require 'rbcurse/rtabbedpane'
22
+ require 'rbcurse/extras/widgets/rtable'
23
+ require 'rbcurse/rscrollpane'
24
+
25
+ class TestTabbedPane
26
+ def initialize
27
+ acolor = $reversecolor
28
+ end
29
+ def run
30
+ $config_hash ||= Variable.new Hash.new
31
+ @window = VER::Window.root_window
32
+ @form = Form.new @window
33
+ $log.debug " MAIN FORM #{@form} "
34
+ r = 1; c = 1;
35
+ h = 20; w = 70
36
+ @tp = RubyCurses::TabbedPane.new @form do
37
+ height h
38
+ width w
39
+ row 2
40
+ col 8
41
+ #button_type :ok
42
+ end
43
+ @tab1 = @tp.add_tab "&Table"
44
+ #f1 = @tab1.form
45
+ f1 = @tp.form @tab1
46
+ raise "form f1 nil" unless f1
47
+ $log.debug " TABLE FORM #{f1} "
48
+
49
+ data = [["Pathetique",3,"Tchaikovsky",3.21, true, "WIP"],
50
+ ["Ali Maula Ali Maula",3,"NFAK",3.47, true, "WIP"],
51
+ ["Tera Hijr Mera Nasib",92,"Razia Sultan",412, true, "Fin"],
52
+ ["Piano Concerto 4&5",4,"Beethoven",110.0, false, "Cancel"],
53
+ ["Toccata and Fugue",4,"J S Bach",102.72, false, "Postp"],
54
+ ["Symphony No. 3",4,"Henryk Gorecki",102.72, true, "Postp"],
55
+ ["The Great Gig in the Sky",8,"Pink Floyd",12.72, false, "Todo"],
56
+ ["Steppes of Central Asia",9,"Borodin",12.2, false, "WIP"],
57
+ ["Wish You Were Here",8,"Pink Floyd",2.7, false, "Todo"],
58
+ ["Habanera",nil,"Maria Callas",112.7, true, "Cancel"],
59
+ ["Mack the Knife",9,"Loius Armstrong",12.2, false, "Todo"],
60
+ ["Prince Igor",9,"Borodin",16.3, false, "WIP"],
61
+ ["Shahbaaz Qalandar",9,"Nusrat Fateh Ali Khan",12.2, false, "Todo"],
62
+ ["Raag Darbari",9,"Ustad Fateh Ali Khan",12.2, false, "Todo"],
63
+ ["Yaad-e-Mustafa Aisi",9,"Santoo Khan",12.2, true, "Todo"],
64
+ ["Chaconne",4,"Johann S Bach",12.42, true, "Postp"],
65
+ ["Raag Jaunpuri",9,"Ustad Fateh Ali Khan",12.2, false, "Todo"],
66
+ ["Dalaleragita",9,"Vaishnava",12.2, false, "Todo"],
67
+ ["Prasada sevaya",9,"Vaishnava",12.2, false, "Todo"],
68
+ ["Sri Rupamanjiri",9,"Vaishnava",12.2, false, "Todo"],
69
+ ["M Vlast ",9,"Smetana",12.2, false, "Todo"],
70
+ ["Jai Radha Madhava",163,"Jagjit Singh",5.4, false, "WIP"]]
71
+
72
+ colnames = %w[ Song Cat Artist Ratio Flag Status]
73
+ statuses = ["Todo", "WIP", "Fin", "Cancel", "Postp"]
74
+
75
+ atable = Table.new f1 do
76
+ name "mytable"
77
+ row 4
78
+ col 0
79
+ width 78
80
+ height 15
81
+ #title "A Table"
82
+ #title_attrib (Ncurses::A_REVERSE | Ncurses::A_BOLD)
83
+ cell_editing_allowed true
84
+ editing_policy :EDITING_AUTO
85
+ set_data data, colnames
86
+ end
87
+ sel_col = Variable.new 0
88
+ sel_col.value = 0
89
+ tcm = atable.get_table_column_model
90
+ selcolname = atable.get_column_name sel_col.value
91
+ #
92
+ ## key bindings fo atable
93
+ # column widths
94
+ tcm.column(0).width 24
95
+ tcm.column(1).width 5
96
+ tcm.column(2).width 18
97
+ #tcm.column(2).editable false
98
+ tcm.column(3).width 7
99
+ tcm.column(4).width 5
100
+ tcm.column(5).width 8
101
+ atable.configure() do
102
+ bind_key(330) { atable.remove_column(tcm.column(atable.focussed_col)) rescue "" }
103
+ bind_key(?+) {
104
+ acolumn = atable.get_column selcolname
105
+ w = acolumn.width + 1
106
+ acolumn.width w
107
+ #atable.table_structure_changed
108
+ }
109
+ bind_key(?-) {
110
+ acolumn = atable.get_column selcolname
111
+ w = acolumn.width - 1
112
+ if w > 3
113
+ acolumn.width w
114
+ #atable.table_structure_changed
115
+ end
116
+ }
117
+ bind_key(?>) {
118
+ colcount = tcm.column_count-1
119
+ #atable.move_column sel_col.value, sel_col.value+1 unless sel_col.value == colcount
120
+ col = atable.focussed_col
121
+ atable.move_column col, col+1 unless col == colcount
122
+ }
123
+ bind_key(?<) {
124
+ col = atable.focussed_col
125
+ atable.move_column col, col-1 unless col == 0
126
+ #atable.move_column sel_col.value, sel_col.value-1 unless sel_col.value == 0
127
+ }
128
+ #bind_key(KEY_RIGHT) { sel_col.value = sel_col.value+1; current_column sel_col.value}
129
+ #bind_key(KEY_LEFT) { sel_col.value = sel_col.value-1;current_column sel_col.value}
130
+ end
131
+
132
+ @tab2 = @tp.add_tab "&ScrollTable"
133
+ #f2 = @tab2.form
134
+ f2 = @tp.form @tab2
135
+ scroll = ScrollPane.new f2 do
136
+ name "myScroller"
137
+ row 4
138
+ col 0
139
+ width w-2
140
+ height h-2
141
+ end
142
+
143
+ $log.debug " TABLE FORM 2 #{f2} "
144
+ btable = Table.new nil do
145
+ name "mytab2"
146
+ row 0
147
+ col 0
148
+ width 78
149
+ height 15
150
+ #title "A Table"
151
+ #title_attrib (Ncurses::A_REVERSE | Ncurses::A_BOLD)
152
+ cell_editing_allowed true
153
+ editing_policy :EDITING_AUTO
154
+ set_data data, colnames
155
+ end
156
+ sel_col = Variable.new 0
157
+ sel_col.value = 0
158
+ tcm = btable.get_table_column_model
159
+ selcolname = btable.get_column_name sel_col.value
160
+ #
161
+ ## key bindings fo atable
162
+ # column widths
163
+ tcm.column(0).width 24
164
+ tcm.column(1).width 5
165
+ tcm.column(2).width 18
166
+ #tcm.column(2).editable false
167
+ tcm.column(3).width 7
168
+ tcm.column(4).width 5
169
+ tcm.column(5).width 8
170
+ scroll.child(btable)
171
+
172
+ @help = "F1 to quit. Use any key of key combination to see what's caught. #{$0} Check logger too"
173
+ RubyCurses::Label.new @form, {'text' => @help, "row" => r+h+2, "col" => 2, "color" => "yellow"}
174
+ @form.repaint
175
+ @window.wrefresh
176
+ Ncurses::Panel.update_panels
177
+ while((ch = @window.getchar()) != KEY_F1 )
178
+ # @tp.repaint
179
+ @form.handle_key(ch)
180
+ @window.wrefresh
181
+ end
182
+ #@tp.show
183
+ #@tp.handle_keys
184
+ end
185
+ end
186
+ if $0 == __FILE__
187
+ # Initialize curses
188
+ begin
189
+ # XXX update with new color and kb
190
+ VER::start_ncurses # this is initializing colors via ColorMap.setup
191
+ $log = Logger.new((File.join(ENV["LOGDIR"] || "./" ,"rbc13.log")))
192
+ $log.level = Logger::DEBUG
193
+ n = TestTabbedPane.new
194
+ n.run
195
+ rescue => ex
196
+ ensure
197
+ VER::stop_ncurses
198
+ p ex if ex
199
+ p(ex.backtrace.join("\n")) if ex
200
+ $log.debug( ex) if ex
201
+ $log.debug(ex.backtrace.join("\n")) if ex
202
+ end
203
+ end
@@ -0,0 +1,88 @@
1
+ require 'rbcurse/core/util/app'
2
+ require 'fileutils'
3
+ require 'rbcurse/tree/treemodel'
4
+ #require 'rbcurse/common/file'
5
+ require './common/file'
6
+
7
+ def _directories wd
8
+ $log.debug " directories got XXX: #{wd} "
9
+ d = Dir.new(wd)
10
+ ent = d.entries.reject{|e| !File.directory? File.join(wd,e)}
11
+ $log.debug " directories got XXX: #{ent} "
12
+ ent.delete(".");ent.delete("..")
13
+ return ent
14
+ end
15
+ App.new do
16
+ header = app_header "rbcurse #{Rbcurse::VERSION}", :text_center => "Yet Another File Manager", :text_right =>"Directory Lister", :color => :black, :bgcolor => :white#, :attr => Ncurses::A_BLINK
17
+ message "Press Enter to expand/collapse"
18
+
19
+ pwd = Dir.getwd
20
+ #d = Dir.new(pwd)
21
+ #entries = d.entries.reject{|e| !File.directory? e}
22
+ #entries.delete(".");entries.delete("..")
23
+ entries = _directories pwd
24
+ patharray = pwd.split("/")
25
+ # we have an array of path, to add recursively, one below the other`
26
+ nodes = []
27
+ nodes << TreeNode.new(patharray.shift)
28
+ patharray.each do |e|
29
+ nodes << nodes.last.add(e)
30
+ end
31
+ last = nodes.last
32
+ nodes.last.add entries
33
+ model = DefaultTreeModel.new nodes.first
34
+
35
+
36
+
37
+ ht = FFI::NCurses.LINES - 2
38
+ borderattrib = :reverse
39
+ stack :margin_top => 1, :margin => 0, :width => 30 do
40
+ @t = tree :data => model, :height => ht, :border_attrib => borderattrib
41
+ @t.bind :TREE_WILL_EXPAND_EVENT do |node|
42
+ path = File.join(*node.user_object_path)
43
+ dirs = _directories path
44
+ ch = node.children
45
+ ch.each do |e|
46
+ o = e.user_object
47
+ if dirs.include? o
48
+ dirs.delete o
49
+ else
50
+ # delete this child since its no longer present TODO
51
+ end
52
+ end
53
+ message " #{node} will expand: #{path}, #{dirs} "
54
+ node.add dirs
55
+ end
56
+ @t.bind :TREE_SELECTION_EVENT do |ev|
57
+ if ev.state == :SELECTED
58
+ node = ev.node
59
+ path = File.join(*node.user_object_path)
60
+ if File.exists? path
61
+ files = Dir.new(path).entries
62
+ files.delete(".")
63
+ @l.list files
64
+ #TODO show all details in filelist
65
+ @current_path = path
66
+ $log.debug " XXX selected afterseeting lb: #{@l} "
67
+ end
68
+ end
69
+ end # select
70
+ @t.expand_node last #
71
+ @t.mark_parents_expanded last # make parents visible
72
+ end
73
+ stack :margin_top => 1, :margin => 30, :width => 50 do
74
+ @l = listbox :height => ht, :border_attrib => borderattrib
75
+ @l.bind :LIST_SELECTION_EVENT do |ev|
76
+ $log.debug " XXX GOT A LIST EVENT #{ev} "
77
+ message ev.source.selected_value
78
+ file_page ev.source.selected_value if ev.type == :INSERT
79
+ #TODO when selects drill down
80
+ #TODO when selecting, sync tree with this
81
+ end
82
+ # on pressing enter, we edit the file using vi or EDITOR
83
+ @l.bind :PRESS do |ev|
84
+ file_edit ev.text if File.exists? ev.text
85
+ end
86
+ end
87
+ status_line :row => FFI::NCurses.LINES - 1
88
+ end # app
@@ -0,0 +1,280 @@
1
+ require 'rbcurse/experimental/widgets/resultsettextview.rb'
2
+ require 'fileutils'
3
+
4
+ =begin
5
+ # See tabbed pane, and add_cols nad add_rows, on_entr and set_form_row to see cursor issue
6
+ # remove main form
7
+ # don't make a widget just an object
8
+ # let it create own form.
9
+
10
+ # NOTE: experimental, not yet firmed up
11
+ # If you use in application, please copy to some application folder in case i change this.
12
+ # Can be used for print_help_page
13
+ # SUGGESTIONS WELCOME.
14
+ # @since 1.4.1
15
+ module RubyCurses
16
+
17
+ class ResultsetBrowser #< Widget
18
+ #include EventHandler
19
+ include ConfigSetup
20
+ include RubyCurses::Utils
21
+ #dsl_property :xxx
22
+ # I don't think width is actually used, windows width matters. What of height ?
23
+ # THATS WRONG , i cannot eat up window. I should use object dimentsion for pad,
24
+ # not window dimensions
25
+ dsl_accessor :row, :col, :height, :width
26
+ dsl_accessor :should_print_border
27
+
28
+ def initialize win, config={}, &block
29
+ @should_print_border = true
30
+ @v_window = win #form.window
31
+ @window = @v_window
32
+ @focusable = true
33
+ @editable = true
34
+ @old_index = @current_index = 0
35
+ @fields = nil
36
+ config_setup config
37
+ instance_eval &block if block_given?
38
+ init_vars
39
+ end
40
+ def map_keys
41
+ @v_form.bind_key(?\C-n) { @current_index += 1 if @current_index < @rows.count-1 }
42
+ @v_form.bind_key(?\C-p) { @current_index -= 1 if @current_index > 0 }
43
+ @mapped = true
44
+ end
45
+ def init_vars
46
+ @row ||= 0
47
+ @col ||= 0
48
+ @height ||= 15
49
+ @width ||= 50
50
+ @field_offset = 14 # where actual Field should start (leaving space for label)
51
+ @row_offset ||= 0
52
+ @col_offset ||= 1
53
+ @border_offset = 0
54
+ if @should_print_border
55
+ @border_offset = 1
56
+ end
57
+ @v_form = RubyCurses::ScrollForm.new @v_window
58
+ @v_form.display_h(@height-1-@border_offset*2) if @height
59
+ @v_form.display_w(@width-1-@border_offset*2) if @width
60
+ end
61
+ def data=(rows)
62
+ @rows = rows
63
+ end
64
+ def columns=(columns)
65
+ @columns = columns
66
+ h = @columns.count + 2
67
+ w = 150
68
+ #row = 1
69
+ #col = 1
70
+ row = @row + @border_offset
71
+ col = @col + @border_offset
72
+ @v_form.set_pad_dimensions(row, col, h, w)
73
+ @v_form.should_print_border(false) # this should use dimensions of object not window. # 2011-10-12 15:48:14
74
+ # currently I don't have space for any buttons or anything. The form takes all space of the window
75
+ # not of the object defined.
76
+ # I should be able to tell Scrollform to use only thismuch of window.
77
+ end
78
+ def set_form_row
79
+ f = @v_form.get_current_field
80
+ f.set_form_row
81
+ end
82
+ def handle_key ch
83
+ map_keys unless @mapped
84
+ $log.debug "XXX: RB HK got ch "
85
+ ret = @v_form.handle_key ch
86
+ #set_form_row
87
+ if ret == :UNHANDLED
88
+ @v_form.process_key ch, self
89
+ end
90
+ repaint
91
+ @v_window.wrefresh
92
+ end
93
+ def repaint
94
+ @fields ||= _create_fields
95
+ #alert "old #{@old_index} , #{@current_index} "
96
+ if @old_index != @current_index
97
+ #alert "index change"
98
+ row = @rows[@current_index]
99
+ @columns.each_with_index { |e, i|
100
+ value = row[i]
101
+ len = value.to_s.length
102
+ type=@rows[0].types[i]
103
+ if type == "TEXT"
104
+ value = value.gsub(/\n/," ") if value
105
+ end
106
+ f = @fields[i]
107
+ @fields[i].set_buffer(value)
108
+ if f.display_length < len && len < (@width - @field_offset)
109
+ @fields[i].display_length len
110
+ end
111
+ }
112
+ @v_form.repaint
113
+ @window.wrefresh
114
+ Ncurses::Panel.update_panels
115
+ @old_index = @current_index
116
+ end
117
+ end
118
+ # maybe not required since we don't have 2 forms now
119
+ def unused_on_enter
120
+ if $current_key == KEY_BTAB
121
+ c = @v_form.widgets.count-1
122
+ @v_form.select_field c
123
+ else
124
+ @v_form.select_field 0
125
+ end
126
+ end
127
+ private
128
+ def _create_fields
129
+ color = $datacolor
130
+ if @should_print_border
131
+ @v_window.print_border @row, @col, @height-1, @width, color #, Ncurses::A_REVERSE
132
+ @row_offset += 1
133
+ @col_offset += 1
134
+ end
135
+ $log.debug "XXX: ROWS#{@rows}"
136
+ $log.debug "XXX: COLS#{@columns}"
137
+ $log.debug "XXX: row#{@rows[@current_index]}"
138
+ fields = []
139
+ r = @row + @row_offset # row was for where to print the total object, not this
140
+ c = @col + @col_offset + @field_offset # 14 is to leave space for labels
141
+ v_form = @v_form
142
+ @columns.each_with_index { |e, index|
143
+ #break if index >= @height-1 # create only as much space we have, SUCKS but just trying till be scroll
144
+ #$log.debug "XXX: #{r} #{c} EACH #{e}, #{index}, #{@rows[@current_index][index]}"
145
+ value=@rows[@current_index][index]
146
+ type=@rows[0].types[index]
147
+ if type == "TEXT"
148
+ value = value.gsub(/\n/," ") if value
149
+ end
150
+ len = [value.to_s.length, (@width - @field_offset)].min
151
+ f = Field.new v_form do
152
+ name e
153
+ row r
154
+ col c
155
+ bgcolor 'blue'
156
+ highlight_background 'cyan'
157
+ set_buffer value
158
+ display_length len
159
+ set_label Label.new v_form, {'text' => e, 'color'=>'cyan'}
160
+ end
161
+ fields << f
162
+ r += 1
163
+ }
164
+ @v_form.repaint
165
+ @window.wrefresh
166
+ Ncurses::Panel.update_panels
167
+ #$log.debug "XXX: created fields "
168
+ return fields
169
+ end
170
+
171
+ # ADD HERE
172
+
173
+ end # class
174
+ end # module
175
+ module RubyCurses
176
+ # a data viewer for viewing some text or filecontents
177
+ # view filename, :close_key => KEY_RETURN
178
+ # send data in an array
179
+ # view Array, :close_key => KEY_RETURN, :layout => [0,0,23,80]
180
+ # when passing layout reserve 4 rows for window and border. So for 2 lines of text
181
+ # give 6 rows.
182
+ class Browser
183
+ def self.browse_sql dbname, tablename, sql, config={} #:yield: ???
184
+ raise "file not found" unless File.exist? dbname
185
+ require 'sqlite3'
186
+ db = SQLite3::Database.new(dbname)
187
+ columns, *rows = db.execute2(sql)
188
+ #$log.debug "XXX COLUMNS #{sql} "
189
+ content = rows
190
+ return nil if content.nil? or content[0].nil?
191
+ datatypes = content[0].types
192
+ self.browse db, tablename, columns, rows, config
193
+ end
194
+ # @param filename as string or content as array
195
+ # @yield textview object for further configuration before display
196
+ # NOTE: i am experimentally yielding textview object so i could supress borders
197
+ # just for kicks, but on can also bind_keys or events if one wanted.
198
+ #def self.view what, config={} #:yield: textview
199
+ def self.browse dbconn, tablename, columns, rows, config={} #:yield: ???
200
+ wt = 0 # top margin
201
+ wl = 0 # left margin
202
+ wh = Ncurses.LINES-wt-3 # height, goes to bottom of screen
203
+ ww = Ncurses.COLS-wl-3 # width, goes to right end
204
+ wt, wl, wh, ww = config[:layout] if config.has_key? :layout
205
+
206
+ fp = config[:title] || ""
207
+ pf = config.fetch(:print_footer, true)
208
+ ta = config.fetch(:title_attrib, 'bold')
209
+ fa = config.fetch(:footer_attrib, 'bold')
210
+
211
+ wh = Ncurses.LINES-0
212
+ ww = Ncurses.COLS-0
213
+ layout = { :height => wh, :width => ww, :top => wt, :left => wl }
214
+ #v_window = config[:window] # using previous window cause crash seg fault
215
+ #v_window ||= VER::Window.new(layout) # copywin gives -1 and prints nothing
216
+ v_window = VER::Window.root_window
217
+ v_window.printstring 0, 30, "Database Browser Demo", $datacolor
218
+ @form = RubyCurses::Form.new v_window # only for some widgets that are not editable
219
+ header = app_header "rbcurse ", :text_center => "ResultsetBrowser Demo", :text_right =>"New Improved!", :color => :black, :bgcolor => :white, :attr => :bold
220
+ sl = status_line :row => v_window.height == 0 ? Ncurses.LINES-1 : v.window.height-1
221
+ sl.command { "Record Navigation: C-n C-p. Scrolling M-n, M-p, M-l, M-h" }
222
+
223
+ @form.repaint
224
+
225
+ #rb = ResultsetBrowser.new v_form, :row => 2, :col => 2
226
+ rb = ResultsetBrowser.new v_window, :row => 2, :col => 2, :height => 20, :width => 95
227
+ rb.columns = columns
228
+ rb.data = rows
229
+ rb.repaint
230
+
231
+
232
+ # yielding textview so you may further configure or bind keys or events
233
+ begin
234
+ #v_form.repaint
235
+ v_window.wrefresh
236
+ Ncurses::Panel.update_panels
237
+ # allow closing using q and Ctrl-q in addition to any key specified
238
+ # user should not need to specify key, since that becomes inconsistent across usages
239
+ while((ch = v_window.getchar()) != ?\C-q.getbyte(0) )
240
+ break if ch == config[:close_key]
241
+ rb.handle_key ch
242
+ #v_form.handle_key ch
243
+ end
244
+ rescue => err
245
+ $log.error err.to_s
246
+ $log.error err.backtrace.join("\n")
247
+ alert err.to_s
248
+
249
+ ensure
250
+ v_window.destroy if !v_window.nil?
251
+ end
252
+ end
253
+ end # class
254
+ end # module
255
+ =end
256
+ if __FILE__ == $PROGRAM_NAME
257
+ require 'rbcurse/core/util/app'
258
+
259
+ App.new do
260
+ header = app_header "rbcurse ", :text_center => "ResultsetBrowser Demo", :text_right =>"New Improved!", :color => :black, :bgcolor => :white, :attr => :bold
261
+ message "Press F10 to exit from here"
262
+ columns = ["Name","Age","City", "Country"]
263
+ data = [
264
+ [ "Rahul",31, "Delhi","India"],
265
+ [ "Dev",35, "Mumbai","India"],
266
+ [ "Jobs",56, "L.A","U.S.A"],
267
+ [ "Matz",40, "Tokyo","Nippon"]
268
+ ]
269
+
270
+ #RubyCurses::Browser.browse("dummy", "atable", columns, data, :close_key => FFI::NCurses::KEY_F10, :title => "Enter to close") do |t|
271
+ sql = "select id, type, priority, title from bugs"
272
+ sql = "select * from bugs"
273
+ file = "bugzy.sqlite"
274
+ tv = RubyCurses::ResultsetTextView.new @form, :row => 1, :col => 1, :width => 50, :height => 16
275
+ tv.sqlite file, "bugs", sql
276
+ #RubyCurses::Browser.browse_sql("bugzy.sqlite", "bugs", sql, :close_key => FFI::NCurses::KEY_F10, :title => "Enter to close", :window => @window) do |t|
277
+ #end
278
+
279
+ end # app
280
+ end