rbcurse 1.4.0 → 1.4.1.pre2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (142) hide show
  1. data/NOTES +68 -0
  2. data/README.markdown +73 -330
  3. data/TODO2.txt +2 -2
  4. data/VERSION +1 -1
  5. data/examples/abasiclist.rb +8 -2
  6. data/examples/alpmenu.rb +1 -1
  7. data/examples/app.rb +1 -24
  8. data/examples/appdirtree.rb +1 -1
  9. data/examples/appemail.rb +8 -14
  10. data/examples/appemaillb.rb +2 -2
  11. data/examples/appgcompose.rb +7 -5
  12. data/examples/common/file.rb +40 -0
  13. data/examples/{rmail.rb → common/rmail.rb} +0 -0
  14. data/examples/data/README.markdown +9 -0
  15. data/examples/data/brew.txt +38 -0
  16. data/examples/data/color.2 +37 -0
  17. data/examples/data/gemlist.txt +60 -0
  18. data/examples/data/lotr.txt +12 -0
  19. data/examples/data/ports.txt +136 -0
  20. data/examples/data/tasks.txt +27 -0
  21. data/examples/{todocsv.csv → data/todocsv.csv} +0 -0
  22. data/examples/data/unix1.txt +21 -0
  23. data/examples/data/unix2.txt +11 -0
  24. data/examples/dbdemo.rb +49 -14
  25. data/examples/{appgmail.rb → deprecated/appgmail.rb} +1 -1
  26. data/examples/{splitp.rb → deprecated/splitp.rb} +0 -0
  27. data/examples/{testscrolllb.rb → deprecated/testscrolllb.rb} +0 -0
  28. data/examples/{testscrollp.rb → deprecated/testscrollp.rb} +0 -0
  29. data/examples/{testscrollta.rb → deprecated/testscrollta.rb} +0 -0
  30. data/examples/{testscrolltable.rb → deprecated/testscrolltable.rb} +0 -0
  31. data/examples/{testsplit.rb → deprecated/testsplit.rb} +0 -0
  32. data/examples/{testsplit2.rb → deprecated/testsplit2.rb} +0 -0
  33. data/examples/{testsplit3.rb → deprecated/testsplit3.rb} +0 -0
  34. data/examples/{testsplit3_1.rb → deprecated/testsplit3_1.rb} +0 -0
  35. data/examples/{testsplit3a.rb → deprecated/testsplit3a.rb} +0 -0
  36. data/examples/{testsplit3b.rb → deprecated/testsplit3b.rb} +0 -0
  37. data/examples/{testsplitta.rb → deprecated/testsplitta.rb} +0 -0
  38. data/examples/{testsplittv.rb → deprecated/testsplittv.rb} +0 -0
  39. data/examples/{testsplittvv.rb → deprecated/testsplittvv.rb} +0 -0
  40. data/examples/{testtpane.rb → deprecated/testtpane.rb} +0 -0
  41. data/examples/{testtpane2.rb → deprecated/testtpane2.rb} +0 -0
  42. data/examples/{testtpanetable.rb → deprecated/testtpanetable.rb} +0 -0
  43. data/examples/dirtree.rb +17 -7
  44. data/examples/experimental/resultsetdemo.rb +280 -0
  45. data/examples/experimental/testmform.rb +35 -0
  46. data/examples/{testscroller.rb → experimental/testscroller.rb} +1 -19
  47. data/examples/experimental/teststackflow.rb +111 -0
  48. data/examples/menu1.rb +1 -0
  49. data/examples/multispl.rb +4 -4
  50. data/examples/newmessagebox.rb +130 -0
  51. data/examples/newtabbedwindow.rb +100 -0
  52. data/examples/newtesttabp.rb +0 -3
  53. data/examples/qdfilechooser.rb +0 -3
  54. data/examples/rfe.rb +134 -18
  55. data/examples/rfe_renderer.rb +48 -2
  56. data/examples/sqlc.rb +2 -1
  57. data/examples/sqlm.rb +0 -2
  58. data/examples/table1.rb +1 -7
  59. data/examples/term2.rb +4 -1
  60. data/examples/test1.rb +0 -5
  61. data/examples/test2.rb +42 -31
  62. data/examples/testapp2.rb +8 -1
  63. data/examples/testchars.rb +0 -4
  64. data/examples/testcombo.rb +5 -9
  65. data/examples/testkeypress.rb +0 -3
  66. data/examples/testmenu.rb +0 -4
  67. data/examples/testmulticomp.rb +3 -5
  68. data/examples/testmulticontainer.rb +94 -0
  69. data/examples/testtable.rb +0 -5
  70. data/examples/testtabp.rb +16 -18
  71. data/examples/testtodo.rb +1 -5
  72. data/examples/testwsshortcuts.rb +64 -0
  73. data/examples/testwsshortcuts2.rb +126 -0
  74. data/examples/viewtodo.rb +1 -4
  75. data/lib/rbcurse.rb +1 -1
  76. data/lib/rbcurse/app.rb +92 -69
  77. data/lib/rbcurse/applicationheader.rb +46 -6
  78. data/lib/rbcurse/celleditor.rb +1 -9
  79. data/lib/rbcurse/comboboxcellrenderer.rb +0 -4
  80. data/lib/rbcurse/common/ansiparser.rb +117 -0
  81. data/{examples → lib/rbcurse/common}/appmethods.rb +25 -0
  82. data/lib/rbcurse/common/basestack.rb +407 -0
  83. data/lib/rbcurse/common/bordertitle.rb +41 -0
  84. data/lib/rbcurse/common/chunk.rb +177 -0
  85. data/lib/rbcurse/common/colorparser.rb +71 -0
  86. data/lib/rbcurse/common/keydefs.rb +30 -0
  87. data/lib/rbcurse/common/widgetshortcuts.rb +302 -0
  88. data/lib/rbcurse/deprecated/README.markdown +12 -0
  89. data/lib/rbcurse/{rscrollpane.rb → deprecated/rscrollpane.rb} +0 -0
  90. data/lib/rbcurse/{rsplitpane.rb → deprecated/rsplitpane.rb} +0 -0
  91. data/lib/rbcurse/{rsplitpane2.rb → deprecated/rsplitpane2.rb} +0 -0
  92. data/lib/rbcurse/{rviewport.rb → deprecated/rviewport.rb} +0 -0
  93. data/lib/rbcurse/experimental/README.markdown +14 -0
  94. data/lib/rbcurse/experimental/resultsettextview.rb +585 -0
  95. data/lib/rbcurse/experimental/stackflow.rb +478 -0
  96. data/lib/rbcurse/extras/bottomline.rb +85 -16
  97. data/lib/rbcurse/extras/box.rb +58 -0
  98. data/lib/rbcurse/extras/directorylist.rb +1 -1
  99. data/lib/rbcurse/extras/horizlist.rb +203 -0
  100. data/lib/rbcurse/extras/listselectable.rb +8 -0
  101. data/lib/rbcurse/extras/multiform.rb +330 -0
  102. data/lib/rbcurse/extras/multilinelabel.rb +142 -0
  103. data/lib/rbcurse/extras/newmessagebox.rb +328 -0
  104. data/lib/rbcurse/extras/newtabbedpane.rb +612 -0
  105. data/lib/rbcurse/extras/newtabbedwindow.rb +68 -0
  106. data/lib/rbcurse/extras/padreader.rb +189 -0
  107. data/lib/rbcurse/extras/rcomboedit.rb +256 -0
  108. data/lib/rbcurse/extras/resultsetbrowser.rb +281 -0
  109. data/lib/rbcurse/extras/statusline.rb +44 -6
  110. data/lib/rbcurse/extras/tabularwidget.rb +141 -104
  111. data/lib/rbcurse/extras/textpad.rb +516 -0
  112. data/lib/rbcurse/extras/viewer.rb +2 -0
  113. data/lib/rbcurse/io.rb +120 -3
  114. data/lib/rbcurse/listcellrenderer.rb +2 -1
  115. data/lib/rbcurse/listkeys.rb +1 -1
  116. data/lib/rbcurse/listscrollable.rb +72 -7
  117. data/lib/rbcurse/rbasiclistbox.rb +64 -12
  118. data/lib/rbcurse/rchangeevent.rb +0 -1
  119. data/lib/rbcurse/rcombo.rb +54 -59
  120. data/lib/rbcurse/rcommandwindow.rb +46 -10
  121. data/lib/rbcurse/rcontainer.rb +415 -0
  122. data/lib/rbcurse/rdialogs.rb +242 -165
  123. data/lib/rbcurse/rinputdataevent.rb +0 -1
  124. data/lib/rbcurse/rlistbox.rb +19 -9
  125. data/lib/rbcurse/rmessagebox.rb +1 -5
  126. data/lib/rbcurse/rmulticontainer.rb +64 -61
  127. data/lib/rbcurse/rmultitextview.rb +0 -2
  128. data/lib/rbcurse/rpopupmenu.rb +0 -2
  129. data/lib/rbcurse/rscrollform.rb +61 -12
  130. data/lib/rbcurse/rtabbedpane.rb +89 -73
  131. data/lib/rbcurse/rtabbedwindow.rb +53 -211
  132. data/lib/rbcurse/rtable.rb +0 -2
  133. data/lib/rbcurse/rtextarea.rb +14 -14
  134. data/lib/rbcurse/rtextview.rb +165 -50
  135. data/lib/rbcurse/rvimsplit.rb +15 -12
  136. data/lib/rbcurse/rwidget.rb +404 -150
  137. data/lib/rbcurse/table/tablecellrenderer.rb +1 -4
  138. data/lib/rbcurse/table/tabledatecellrenderer.rb +0 -3
  139. data/lib/ver/ncurses.rb +1 -9
  140. data/lib/ver/rpad.rb +375 -0
  141. data/lib/ver/window.rb +262 -440
  142. metadata +73 -31
@@ -0,0 +1,27 @@
1
+ Field to have history which pops up
2
+ App to have layout objects @1.6
3
+ F2 menu to have context sensitive items
4
+ SL and Dock events Hide. Move ...
5
+ Stack and Flow to be objects @1.5
6
+ ability to share directory options and functions across dir apps
7
+ add event to form, key_resize
8
+ app: add popup @1.5
9
+ app: widgets can register with dock @1.5
10
+ can use textpad in resultsetdb view to make things simpler
11
+ colored module that allows row-wise coloring for all multirow wids
12
+ find_file like microemacs @1.5
13
+ motion options in textview and lists gg G cYcEcDcB zz zt zb etc
14
+ registering command with Alt-X SL and Dock
15
+ schemes (color) @1.5
16
+ textview etc can have source. also module to recog file type,fmt
17
+ use textpad for lists etc
18
+ window.close can have a event so cleanup of any widget can be done
19
+ Backward char search using F
20
+ add progress bar to StatusWindow
21
+ bottomline options global @1.5
22
+ catch_alt_digits maybe at form level not global
23
+ widgets needs to expose mapped keys in some easy way
24
+ color_pair as :red_on_black
25
+ confirm quit option, and call a proc before quitting
26
+ elusive error if row not given in button
27
+ rpopupmenu and rmenu share same class names
File without changes
@@ -0,0 +1,21 @@
1
+ Eric S. Raymond, in his book The Art of Unix Programming,[2] summarizes the Unix philosophy as the widely-used KISS Principle of "Keep it Simple, Stupid."[3] He also provides a series of design rules:
2
+
3
+ * Rule of Modularity: Write simple parts connected by clean interfaces.
4
+ * Rule of Clarity: Clarity is better than cleverness.
5
+ * Rule of Composition: Design programs to be connected to other programs.
6
+ * Rule of Separation: Separate policy from mechanism; separate interfaces from engines.
7
+ * Rule of Simplicity: Design for simplicity; add complexity only where you must.
8
+ * Rule of Parsimony: Write a big program only when it is clear by demonstration that nothing else will do.
9
+ * Rule of Transparency: Design for visibility to make inspection and debugging easier.
10
+ * Rule of Robustness: Robustness is the child of transparency and simplicity.
11
+ * Rule of Representation: Fold knowledge into data so program logic can be stupid and robust.[4]
12
+ * Rule of Least Surprise: In interface design, always do the least surprising thing.
13
+ * Rule of Silence: When a program has nothing surprising to say, it should say nothing.
14
+ * Rule of Repair: When you must fail, fail noisily and as soon as possible.
15
+ * Rule of Economy: Programmer time is expensive; conserve it in preference to machine time.
16
+ * Rule of Generation: Avoid hand-hacking; write programs to write programs when you can.
17
+ * Rule of Optimization: Prototype before polishing. Get it working before you optimize it.
18
+ * Rule of Diversity: Distrust all claims for "one true way".
19
+ * Rule of Extensibility: Design for the future, because it will be here sooner than you think.
20
+
21
+
@@ -0,0 +1,11 @@
1
+ 1. Small is beautiful.
2
+ 2. Make each program do one thing well.
3
+ 3. Build a prototype as soon as possible.
4
+ 4. Choose portability over efficiency.
5
+ 5. Store data in flat text files.
6
+ 6. Use software leverage to your advantage.
7
+ 7. Use shell scripts to increase leverage and portability.
8
+ 8. Avoid captive user interfaces.
9
+ 9. Make every program a filter.
10
+
11
+
data/examples/dbdemo.rb CHANGED
@@ -1,5 +1,6 @@
1
1
  require 'rbcurse/app'
2
2
  require 'sqlite3'
3
+ #require 'rbcurse/experimental/resultsettextview.rb'
3
4
  require 'rbcurse/undomanager'
4
5
 
5
6
  # @return array of table names from selected db file
@@ -73,7 +74,7 @@ def create_popup array, selection_mode=:single, &blk
73
74
  end
74
75
  end
75
76
 
76
- def view_data fields="*", name
77
+ def view_data fields='*', name
77
78
  stmt = "select #{fields} from #{name}"
78
79
  stmt << $where_string if $where_string
79
80
  stmt << $order_string if $order_string
@@ -107,12 +108,18 @@ App.new do
107
108
  $current_table = nil
108
109
  $current_db = nil # "testd.db"
109
110
  connect $current_db if $current_db
111
+ def which_field
112
+ alert "curent field is #{form.get_current_field} "
113
+ end
110
114
 
115
+ def get_commands
116
+ %w{ which_field }
117
+ end
111
118
  def help_text
112
119
  <<-eos
113
- APPEMAIL HELP
120
+ DBDEMO HELP
114
121
 
115
- This is some help text for appemail.
122
+ This is some help text for dbdemo.
116
123
  We are testing out this feature.
117
124
 
118
125
  Alt-d - Select a database
@@ -132,6 +139,15 @@ App.new do
132
139
 
133
140
  Alt-x - Command mode (<tab> to see commands and select)
134
141
  : - Command mode
142
+ Alt-z - Commands in TextArea
143
+
144
+ DB BROWSER KEYS
145
+
146
+ , Prev row (mnemonic <)
147
+ . Next row (mnemonic >)
148
+ < First row
149
+ > Last row
150
+
135
151
  F10 - Quit application
136
152
 
137
153
 
@@ -213,7 +229,7 @@ App.new do
213
229
  end
214
230
  end
215
231
  menu "Others" do
216
- require './appmethods.rb'
232
+ require 'rbcurse/common/appmethods.rb'
217
233
  item "Shell Output" do
218
234
  command { shell_output }
219
235
  end
@@ -226,16 +242,22 @@ App.new do
226
242
  mb.color = :white
227
243
  mb.bgcolor = :blue
228
244
  @form.set_menu_bar mb
229
- stack :margin => 0 do
245
+ tv = nil
246
+ col1w = 20
247
+ stack :margin => 0, :width => col1w do
230
248
  text = "No tables"
231
249
  if !$current_db
232
250
  text = "Select DB first. Press Alt-D"
233
251
  end
234
- tlist = basiclist :name => "tlist", :list => [text], :title => "Tables", :height => 10
252
+ tlist = basiclist :name => "tlist", :list => [text], :title => "Tables", :height => 10,
253
+ :selected_color => 'cyan', :selected_bgcolor => 'black' , :selected_attr => Ncurses::A_REVERSE,
254
+ :help_text => "Enter to View complete table, Space to select table and view columns",
255
+ :should_show_focus => true
235
256
  tlist.bind(:PRESS) do |eve|
236
257
  if $current_db
237
258
  # get data of table
238
259
  view_data eve.text
260
+ tv.sqlite $current_db, eve.text, "select * from #{eve.text} "
239
261
  else
240
262
  ask_databases
241
263
  end
@@ -245,7 +267,9 @@ App.new do
245
267
  #$current_table = eve.text if $db
246
268
  end
247
269
  clist = basiclist :name => "clist", :list => ["No columns"], :title => "Columns", :height => 14,
248
- :selection_mode => :multiple
270
+ :selection_mode => :multiple,
271
+ :selected_color => 'cyan', :selected_bgcolor => 'black' , :selected_attr => Ncurses::A_REVERSE,
272
+ :help_text => "Enter to View selected fields, Space to select columns, w - where, o-order"
249
273
  tlist.bind(:LIST_SELECTION_EVENT) do |eve|
250
274
  $selected_table = eve.source[eve.firstrow]
251
275
  $current_table = $selected_table
@@ -288,16 +312,23 @@ App.new do
288
312
  $log.debug "XXX: ORDER: #{$order_columns}. Press F4 when done"
289
313
  }
290
314
  @statusline = status_line
315
+ #wg = get_color($datacolor, 'white','green')
316
+ #wb = get_color($datacolor, 'white','blue')
291
317
  @statusline.command {
292
318
  # trying this out. If you want a persistent message that remains till the next on
293
319
  # then send it in as $status_message
294
320
  text = $status_message.value || ""
295
321
  if !$current_db
296
- "%-20s [%-s] %s" % [ Time.now, "Select a Database", text]
322
+ #"[%-s] %s" % [ "Select a Database", text]
323
+ "[%-s] %s" % [ "#[bg=red,fg=yellow]Select a Database#[end]", text]
324
+ #[ [nil, "%-22s" % Time.now, nil], [$errorcolor, " [Select a Database ]", FFI::NCurses::A_BOLD], [nil, text, nil] ]
297
325
  elsif !$current_table
298
- "%-20s [DB: %-s | %-s ] %s" % [ Time.now, $current_db || "None", $current_table || "Select a table", text]
326
+ "[DB: #[fg=white,bg=blue]%-s#[end] | %-s ] %s" % [ $current_db || "None", $current_table || "#[bg=red,fg=yellow]Select a table#[end]", text]
327
+ #[ [nil, "%-22s [DB: %-s | " % [Time.now, $current_db || "None" ],nil], [$errorcolor, " Select a Table ]", FFI::NCurses::A_BOLD], [nil, text, nil] ]
299
328
  else
300
- "%-20s [DB: %-s | %-s ] %s" % [ Time.now, $current_db || "None", $current_table || "----", text]
329
+ "DB: #[fg=white,bg=green,bold]%-s#[end] | #[bold]%-s#[end] ] %s" % [ $current_db || "None", $current_table || "----", text]
330
+ #[ [nil, "%-22s [DB: " % Time.now, nil], [wb, " #{$current_db} ", FFI::NCurses::A_BOLD],
331
+ #[wg, $current_table || "----", FFI::NCurses::A_BOLD], [nil, text, nil] ]
301
332
  end
302
333
  }
303
334
  @adock = nil
@@ -362,7 +393,7 @@ App.new do
362
393
  @form.bind_key(?\M-d) do
363
394
  ask_databases
364
395
  end
365
- @form.bind_key(Ncurses::KEY_F4) do
396
+ @form.bind_key(FFI::NCurses::KEY_F4) do
366
397
  $where_string = nil
367
398
  $order_string = nil
368
399
  if $where_columns
@@ -384,8 +415,8 @@ App.new do
384
415
  end
385
416
  end
386
417
  end # stack
387
- stack :margin => 50, :width => :EXPAND do
388
- tarea = textarea :name => 'tarea', :height => 20, :title => 'Sql Statement'
418
+ stack :margin => col1w+1, :width => :EXPAND do
419
+ tarea = textarea :name => 'tarea', :height => 5, :title => 'Sql Statement'
389
420
  undom = SimpleUndo.new tarea
390
421
  tarea.bind_key(Ncurses::KEY_F4) do
391
422
  text = tarea.get_text
@@ -426,7 +457,7 @@ App.new do
426
457
  @adock.mode :normal
427
458
  } # M-z
428
459
  flow do
429
- button_row = 17
460
+ #button_row = 17
430
461
  button "Save" do
431
462
  @cmd_history ||= []
432
463
  filename = ask("File to append contents to: ") { |q| q.default = @oldfilename; q.history = @cmd_history }
@@ -456,5 +487,9 @@ App.new do
456
487
  #ok_button = button( [button_row,30], "OK", {:mnemonic => 'O'}) do
457
488
  #end
458
489
  end
490
+ blank
491
+ #tv = RubyCurses::ResultsetTextView.new @form, :row => 1, :col => 1, :width => 50, :height => 16
492
+ tv = resultsettextview :name => 'resultset', :height => 18 , :title => 'DB Browser', :print_footer => true
493
+
459
494
  end
460
495
  end # app
@@ -686,7 +686,7 @@ App.new do
686
686
  @dirs = list_box :list => model, :height => ht, :border_attrib => borderattrib, :suppress_borders => true
687
687
  @dirs.one_key_selection = false
688
688
 
689
- # we override so as to only print basename. Also, print unread count
689
+ # we override/open instance so as to only print basename. Also, print unread count
690
690
  def @dirs.convert_value_to_text(text, crow)
691
691
  str = text.dup
692
692
  if $unread_hash.has_key?(str)
File without changes
File without changes
File without changes
data/examples/dirtree.rb CHANGED
@@ -1,6 +1,8 @@
1
1
  require 'rbcurse/app'
2
2
  require 'fileutils'
3
3
  require 'rbcurse/tree/treemodel'
4
+ #require 'rbcurse/common/file'
5
+ require './common/file'
4
6
 
5
7
  def _directories wd
6
8
  $log.debug " directories got XXX: #{wd} "
@@ -32,7 +34,7 @@ App.new do
32
34
 
33
35
 
34
36
 
35
- ht = 24
37
+ ht = FFI::NCurses.LINES - 2
36
38
  borderattrib = :reverse
37
39
  stack :margin_top => 1, :margin => 0, :width => 30 do
38
40
  @t = tree :data => model, :height => ht, :border_attrib => borderattrib
@@ -55,12 +57,14 @@ App.new do
55
57
  if ev.state == :SELECTED
56
58
  node = ev.node
57
59
  path = File.join(*node.user_object_path)
58
- files = Dir.new(path).entries
59
- files.delete(".")
60
- @l.list files
61
- #TODO show all details in filelist
62
- @current_path = path
63
- $log.debug " XXX selected afterseeting lb: #{@l} "
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
64
68
  end
65
69
  end # select
66
70
  @t.expand_node last #
@@ -71,8 +75,14 @@ App.new do
71
75
  @l.bind :LIST_SELECTION_EVENT do |ev|
72
76
  $log.debug " XXX GOT A LIST EVENT #{ev} "
73
77
  message ev.source.selected_value
78
+ file_page ev.source.selected_value if ev.type == :INSERT
74
79
  #TODO when selects drill down
75
80
  #TODO when selecting, sync tree with this
76
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
77
86
  end
87
+ status_line :row => FFI::NCurses.LINES - 1
78
88
  end # app
@@ -0,0 +1,280 @@
1
+ require 'rbcurse/extras/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/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