rbcurse 1.5.0 → 1.5.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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,121 @@
1
+ module RubyCurses
2
+
3
+ ##
4
+ # This is a basic list cell renderer that will render the to_s value of anything.
5
+ # Using alignment one can use for numbers too.
6
+ # However, for booleans it will print true and false. If editing, you may want checkboxes
7
+ class RfeRenderer < ListCellRenderer
8
+ def initialize text="", config={}, &block
9
+ super
10
+ @orig_bgcolor = @bgcolor
11
+ @orig_color = @color
12
+ @orig_attr = @attr
13
+ # we need to refer to file types, executable, dir, link, otherwise we'll go crazy
14
+ @color_hash = {
15
+ '.rb' => [get_color($datacolor, 'red', 'black'), 0],
16
+ '.txt' => [get_color($datacolor, 'white', 'black'), 0],
17
+ '.gemspec' => [get_color($datacolor, 'yellow', 'black'), 0],
18
+ '.gem' => [get_color($datacolor, 'yellow', 'black'), 0],
19
+ '.c' => [get_color($datacolor, 'green', 'black'), 0],
20
+ '.py' => [get_color($datacolor, 'green', 'black'), 0],
21
+ '.tgz' => [get_color($datacolor, 'red', 'black'), get_attrib('bold')],
22
+ '.gz' => [get_color($datacolor, 'red', 'black'), 0],
23
+ '.zip' => [get_color($datacolor, 'red', 'black'), 0],
24
+ '.jar' => [get_color($datacolor, 'red', 'black'), 0],
25
+ '.html' => [get_color($datacolor, 'green', 'black'), get_attrib('reverse')],
26
+ "" => [get_color($datacolor, 'yellow', 'black'), get_attrib('bold')],
27
+ '.jpg' => [get_color($datacolor, 'magenta', 'black'), 0],
28
+ '.png' => [get_color($datacolor, 'magenta', 'black'), 0],
29
+ '.sh' => [get_color($datacolor, 'red', 'black'), 0],
30
+ '.mp3' => [get_color($datacolor, 'cyan', 'blue'), 0],
31
+ '.bak' => [get_color($datacolor, 'magenta', 'black'), 0],
32
+ '.tmp' => [get_color($datacolor, 'black', 'blue'), 0],
33
+ '.pl' => [get_color($datacolor, 'green', 'black'), 0],
34
+ '.java' => [get_color($datacolor, 'cyan', 'blue'), 0],
35
+ '.class' => [get_color($datacolor, 'magenta', 'black'), 0],
36
+ '.pyc' => [get_color($datacolor, 'magenta', 'black'), 0],
37
+ '.o' => [get_color($datacolor, 'magenta', 'black'), 0],
38
+ '.a' => [get_color($datacolor, 'magenta', 'black'), 0],
39
+ '.lib' => [get_color($datacolor, 'magenta', 'black'), 0]
40
+ }
41
+ end
42
+
43
+ # override parent method to set color_pair and attr for different kind of files
44
+ def select_colors focussed, selected
45
+ ext = File.extname(@path)
46
+ c = @color_hash[ext]
47
+ c = [$datacolor, FFI::NCurses::A_NORMAL] unless c
48
+ if File.directory? @path
49
+ c = [get_color($datacolor, 'blue', 'black'), FFI::NCurses::A_BOLD]
50
+ end
51
+ @color_pair, @attr = *c
52
+ if selected
53
+ #@attr = FFI::NCurses::A_UNDERLINE | FFI::NCurses::A_BOLD # UL not avaible on screen
54
+ @attr = FFI::NCurses::A_REVERSE | FFI::NCurses::A_BOLD
55
+ @color_pair = $datacolor
56
+ end
57
+ if focussed
58
+ @attr = FFI::NCurses::A_REVERSE # | FFI::NCurses::A_BOLD
59
+ end
60
+ end
61
+ #
62
+ def repaint graphic, r=@row,c=@col, row_index=-1, value=@text, focussed=false, selected=false
63
+
64
+ @bgcolor = @orig_bgcolor
65
+ @color = @orig_color
66
+ @row_attr = @orig_attr
67
+ # XXX ouch, when we delete from list, must delete from here too.
68
+ value = @parent.entries[row_index]
69
+ if value[0,1]=="/"
70
+ path = value.dup
71
+ else
72
+ path = @parent.cur_dir()+"/"+value
73
+ end
74
+ @path = path # i need it in select_color
75
+ begin
76
+ stat = File.stat(path)
77
+ if File.directory? path
78
+ @row_attr = Ncurses::A_BOLD
79
+ #@color = 'yellow'
80
+ end
81
+ value = format_string(value, path, stat)
82
+ super
83
+
84
+ rescue => err
85
+ $log.debug " rfe_renderer: #{err}"
86
+ end
87
+
88
+ end
89
+ GIGA_SIZE = 1073741824.0
90
+ MEGA_SIZE = 1048576.0
91
+ KILO_SIZE = 1024.0
92
+
93
+ # Return the file size with a readable style.
94
+ def readable_file_size(size, precision)
95
+ case
96
+ #when size == 1 then "1 B"
97
+ when size < KILO_SIZE then "%d B" % size
98
+ when size < MEGA_SIZE then "%.#{precision}f K" % (size / KILO_SIZE)
99
+ when size < GIGA_SIZE then "%.#{precision}f M" % (size / MEGA_SIZE)
100
+ else "%.#{precision}f G" % (size / GIGA_SIZE)
101
+ end
102
+ end
103
+ def date_format t
104
+ t.strftime "%Y/%m/%d"
105
+ end
106
+ def format_string fn, path,stat
107
+ max_len = 30
108
+ f = fn.dup
109
+ if File.directory? path
110
+ #"%-*s\t(dir)" % [max_len,f]
111
+ #f = "/"+f # disallows search on keypress
112
+ f = "/"+f
113
+ end
114
+ if f.size > max_len
115
+ f = f[0..max_len-1]
116
+ end
117
+ "%-*s %10s %s" % [max_len,f, readable_file_size(stat.size,1), date_format(stat.mtime)]
118
+ end
119
+ # ADD HERE
120
+ end
121
+ end
data/examples/sqlc.rb ADDED
@@ -0,0 +1,454 @@
1
+ ## rkumar, 2009
2
+ #
3
+ #DEPRECATED. See sqlm.rb or sqlt.rb in which i use a TabularWidget instead of Table.
4
+ #AVOID USING TabbedPane till its rewritten 1.3.2 or so.
5
+
6
+ #
7
+ ############ WARNING ##############################################################
8
+ # TabbedPanes seem to have stopped displaying at some points
9
+ # after moving to FFI-Ncurses. And i've not been able to locate the point.
10
+ # This is one subtle difference between ncurses and ffi-ncurses.
11
+ # So i will scrap this and do a fresh clean rewrite of TabbedPane class.
12
+ # OKAY I've got them fixed.
13
+ #
14
+ ###################################################################################
15
+ # Sample demo of various widgets and their interaction.
16
+ # This is a simple sql client which allows table / column selection, construction
17
+ # of SQL queries, and multiple resultsets.
18
+ # Use C-q to quit, Alt-Tab to move out of Table to next field.
19
+ # Please see bind_key statements in this app for some key bindings in table.
20
+ # There are also key bindings in tabbedpanes and textarea's that will help alot.
21
+ # This demo uses a tabbedpane so we can have the results of many sql statements and not
22
+ # need to keep reissuing. Its better to use a multitextview or multicontainer
23
+ # than a tabbedpane for such use.
24
+ #
25
+ require 'logger'
26
+ require 'sqlite3'
27
+ require 'rbcurse'
28
+ require 'rbcurse/core/widgets/rcombo'
29
+ require 'rbcurse/core/widgets/rtextarea'
30
+ require 'rbcurse/extras/widgets/rtable'
31
+ #require 'rbcurse/table/tablecellrenderer'
32
+ #require 'rbcurse/extras/include/comboboxcellrenderer'
33
+ #require 'rbcurse/core/widgets/keylabelprinter'
34
+ require 'rbcurse/core/widgets/applicationheader'
35
+ require 'rbcurse/core/include/action' # not used here
36
+ require 'rbcurse/rtabbedpane'
37
+
38
+ # pls get testd.db from
39
+ # http://www.benegal.org/files/screen/testd.db
40
+ # or put some other sqlite3 db name there.
41
+ # or create using sqlite3 testd.db < data.txt
42
+
43
+ ## must give me @content, @columns, @datatypes (opt)
44
+ class Datasource
45
+ # attr_reader :field_length # specified by user, length of row in display table
46
+ attr_accessor :columns # names of columns in array
47
+ attr_accessor :datatypes # array of datatyps of columns required to align: int, real, float, smallint
48
+ attr_accessor :content # 2 dim data
49
+ attr_accessor :user_columns # columnnames provided by user, overrides what is generated for display
50
+ # attr_reader :sqlstring # specified by user
51
+
52
+ # constructor
53
+ def initialize(config={}, &block)
54
+ @content = []
55
+ @columns = nil # actual db columnnames -- needed to figure out datatypes
56
+ @user_columns = nil # user specified db columnnames, overrides what may be provided
57
+ @datatypes = nil
58
+ # @rows = nil
59
+ # @sqlstring = nil
60
+ # @command = nil
61
+
62
+ instance_eval(&block) if block_given?
63
+ end
64
+ def connect dbname
65
+ raise " #{dbname} does not exist. Please fetch from http://www.benegal.org/files/screen/testd.db" if !File.exists?(dbname)
66
+ @db = SQLite3::Database.new(dbname)
67
+ end
68
+ # get columns and datatypes, prefetch
69
+ def get_data command
70
+ @columns, *rows = @db.execute2(command)
71
+ $log.debug "XXX COLUMNS #{command} : #{@columns.count}: #{@columns} "
72
+ @content = rows
73
+ return nil if @content.nil? or @content[0].nil?
74
+ @datatypes = @content[0].types #if @datatypes.nil?
75
+ @command = command
76
+ return @content
77
+ end
78
+ def get_metadata table
79
+ get_data "select * from #{table} limit 1"
80
+ return @columns
81
+ end
82
+ ##
83
+ # returns columns_widths, and updates that variable
84
+ def estimate_column_widths tablewidth, columns
85
+ colwidths = {}
86
+ min_column_width = (tablewidth/columns.length) -1
87
+ $log.debug("min: #{min_column_width}, #{tablewidth}")
88
+ @content.each_with_index do |row, cix|
89
+ break if cix >= 20
90
+ row.each_index do |ix|
91
+ col = row[ix]
92
+ colwidths[ix] ||= 0
93
+ colwidths[ix] = [colwidths[ix], col.length].max
94
+ end
95
+ end
96
+ total = 0
97
+ colwidths.each_pair do |k,v|
98
+ name = columns[k.to_i]
99
+ colwidths[name] = v
100
+ total += v
101
+ end
102
+ colwidths["__TOTAL__"] = total
103
+ column_widths = colwidths
104
+ @max_data_widths = column_widths.dup
105
+
106
+ columns.each_with_index do | col, i|
107
+ if @datatypes[i].match(/(real|int)/) != nil
108
+ wid = column_widths[i]
109
+ # cw = [column_widths[i], [8,min_column_width].min].max
110
+ $log.debug("XXX #{wid}. #{columns[i].length}")
111
+ cw = [wid, columns[i].length].max
112
+ $log.debug("int #{col} #{column_widths[i]}, #{cw}")
113
+ elsif @datatypes[i].match(/(date)/) != nil
114
+ cw = [column_widths[i], [12,min_column_width].min].max
115
+ #cw = [12,min_column_width].min
116
+ $log.debug("date #{col} #{column_widths[i]}, #{cw}")
117
+ else
118
+ cw = [column_widths[i], min_column_width].max
119
+ if column_widths[i] <= col.length and col.length <= min_column_width
120
+ cw = col.length
121
+ end
122
+ $log.debug("else #{col} #{column_widths[i]}, #{col.length} #{cw}")
123
+ end
124
+ column_widths[i] = cw
125
+ total += cw
126
+ end
127
+ column_widths["__TOTAL__"] = total
128
+ $log.debug("Estimated col widths: #{column_widths.inspect}")
129
+ @column_widths = column_widths
130
+ return column_widths
131
+ end
132
+
133
+ # added to enable query form to allow movement into table only if
134
+ # there is data 2008-10-08 17:46
135
+ # returns number of rows fetched
136
+ def data_length
137
+ return @content.length
138
+ end
139
+
140
+ end
141
+ def get_key_labels
142
+ key_labels = [
143
+ ['C-q', 'Exit'], nil,
144
+ ['M-s', 'Save'], ['M-m', 'Move']
145
+ ]
146
+ return key_labels
147
+ end
148
+ def get_key_labels_table
149
+ key_labels = [
150
+ ['M-n','NewRow'], ['M-d','DelRow'],
151
+ ['C-x','Select'], nil,
152
+ ['M-0', 'Top'], ['M-9', 'End'],
153
+ ['C-p', 'PgUp'], ['C-n', 'PgDn'],
154
+ ['M-Tab','Nxt Fld'], ['Tab','Nxt Col'],
155
+ ['+','Widen'], ['-','Narrow']
156
+ ]
157
+ return key_labels
158
+ end
159
+ class Sqlc
160
+ def initialize
161
+ @window = VER::Window.root_window
162
+ $catch_alt_digits = false # we want to use Alt-1, 2 for tabs.
163
+ @form = Form.new @window
164
+ @tab_ctr = 0
165
+
166
+ @db = Datasource.new
167
+ @db.connect "testd.db"
168
+ end
169
+ def run
170
+ title = "rbcurse"
171
+ @header = ApplicationHeader.new @form, title, {:text2=>"Demo", :text_center=>"SQL Client using deprecated TabbedPane and Table (see sqlm.rb instead) "}
172
+ status_row = RubyCurses::Label.new @form, {'text' => "", :row => Ncurses.LINES-4, :col => 0, :display_length=>70}
173
+ @status_row = status_row
174
+ # setting ENTER across all objects on a form
175
+ @form.bind(:ENTER) {|f| status_row.text = f.help_text unless f.help_text.nil? }
176
+ r = 1; c = 1;
177
+ @data = [ ["No data"] ]
178
+ data = @data
179
+ colnames = %w[ Result ]
180
+
181
+ ta_ht = 5
182
+ t_width = 78
183
+ sqlarea = TextArea.new @form do
184
+ name "sqlarea"
185
+ row r
186
+ col c
187
+ width t_width
188
+ height ta_ht
189
+ title "Sql Query"
190
+ title_attrib (Ncurses::A_REVERSE | Ncurses::A_BOLD)
191
+ help_text "Enter query and press Run or Meta-r"
192
+ end
193
+ sqlarea << "select * from contacts"
194
+ buttrow = r+ta_ht+1 #Ncurses.LINES-4
195
+ b_run = Button.new @form do
196
+ text "&Run"
197
+ row buttrow
198
+ col c
199
+ help_text "Run query"
200
+ end
201
+ ## We use Action to create a button: to test out ampersand with MI and Button
202
+ b_clear = Button.new @form do
203
+ #action new_act
204
+ text "&Clear"
205
+ row buttrow
206
+ col c+10
207
+ help_text "Clear query entry box "
208
+ end
209
+ b_clear.command {
210
+ sqlarea.remove_all
211
+ sqlarea.focus
212
+ }
213
+
214
+ # using ampersand to set mnemonic
215
+
216
+ b_construct = Button.new @form do
217
+ text "Constr&uct"
218
+ row buttrow
219
+ col c+25
220
+ help_text "Select a table, select columns and press this to construct an SQL"
221
+ end
222
+
223
+ Button.button_layout [b_run, b_clear, b_construct], buttrow, startcol=5, cols=Ncurses.COLS-1, gap=5
224
+
225
+ @tp = create_tabbed_pane @form, buttrow, t_width, c
226
+ @tp.show
227
+ @data = data
228
+
229
+ b_run.command {
230
+ query = sqlarea.get_text
231
+ run_query query
232
+ }
233
+ #
234
+ ## key bindings fo atable
235
+ # column widths
236
+ app = self
237
+ #atable.configure() do
238
+ ##bind_key(330) { atable.remove_column(tcm.column(atable.focussed_col)) rescue "" }
239
+ #bind_key(?+) {
240
+ #acolumn = atable.column atable.focussed_col()
241
+ #w = acolumn.width + 1
242
+ #acolumn.width w
243
+ ##atable.table_structure_changed
244
+ #}
245
+ #bind_key(?-) {
246
+ #acolumn = atable.column atable.focussed_col()
247
+ #w = acolumn.width - 1
248
+ #if w > 3
249
+ #acolumn.width w
250
+ ##atable.table_structure_changed
251
+ #end
252
+ #}
253
+ ## added new method on 2009-10-08 00:47
254
+ #bind_key(?=) {
255
+ #atable.size_columns_to_fit
256
+ #}
257
+ #bind_key(?>) {
258
+ #tcm = atable.get_table_column_model
259
+ #colcount = tcm.column_count-1
260
+ ##atable.move_column sel_col.value, sel_col.value+1 unless sel_col.value == colcount
261
+ #col = atable.focussed_col
262
+ #atable.move_column col, col+1 unless col == colcount
263
+ #}
264
+ #bind_key(?<) {
265
+ #col = atable.focussed_col
266
+ #atable.move_column col, col-1 unless col == 0
267
+ ##atable.move_column sel_col.value, sel_col.value-1 unless sel_col.value == 0
268
+ #}
269
+ ## TODO popup and key labels
270
+ #bind_key(?\M-h, app) {|tab,td| $log.debug " BIND... #{tab.class}, #{td.class}"; app.make_popup atable}
271
+ #end
272
+ #keylabel = RubyCurses::Label.new @form, {'text' => "", "row" => r+table_ht+3, "col" => c, "color" => "yellow", "bgcolor"=>"blue", "display_length"=>60, "height"=>2}
273
+ #eventlabel = RubyCurses::Label.new @form, {'text' => "Events:", "row" => r+table_ht+6, "col" => c, "color" => "white", "bgcolor"=>"blue", "display_length"=>60, "height"=>2}
274
+
275
+ # report some events
276
+ #atable.table_model.bind(:TABLE_MODEL_EVENT){|e| #eventlabel.text = "Event: #{e}"}
277
+ #atable.get_table_column_model.bind(:TABLE_COLUMN_MODEL_EVENT){|e| eventlabel.text = "Event: #{e}"}
278
+
279
+ tablist_ht = 6
280
+ mylist = @db.get_data "select name from sqlite_master"
281
+ # mylist is an Array of SQLite3::ResultSet::ArrayWithTypesAndFields
282
+ raise "Database contains no tables! I need some tables" unless mylist
283
+ mylist.collect!{|x| x[0] } ## 1.9 hack, but will it run on 1.8 ??
284
+ $listdata = Variable.new mylist
285
+ tablelist = Listbox.new @form do
286
+ name "tablelist"
287
+ row 1
288
+ col t_width+2
289
+ width 20
290
+ height tablist_ht
291
+ # list mylist
292
+ list_variable $listdata
293
+ #selection_mode :multiple
294
+ #show_selector true
295
+ title "Tables"
296
+ title_attrib 'reverse'
297
+ help_text "Press ENTER to run * query, Space to select columns"
298
+ end
299
+ #tablelist.bind(:PRESS) { |alist| @status_row.text = "Selected #{alist.current_index}" }
300
+ tablelist.list_selection_model().bind(:LIST_SELECTION_EVENT,tablelist) { |lsm, alist| @status_row.text = "Selected #{alist.current_index}" }
301
+
302
+ collist = []
303
+ $coldata = Variable.new collist
304
+ columnlist = Listbox.new @form do
305
+ name "columnlist"
306
+ row tablist_ht+2
307
+ col t_width+2
308
+ width 20
309
+ height 15
310
+ # list mylist
311
+ list_variable $coldata
312
+ selection_mode :multiple
313
+ #show_selector true
314
+ title "Columns"
315
+ title_attrib 'reverse'
316
+ help_text "Press ENTER to append columns to sqlarea, Space to select"
317
+ end
318
+ ## pressing SPACE on a table populates column list with its columns so they can be selected
319
+ #tablelist.bind_key(32) {
320
+ # Now space trapped at listbox level, need to use event
321
+ tablelist.list_selection_model().bind(:LIST_SELECTION_EVENT,tablelist) { |lsm, alist| @status_row.text = "Selected #{alist.current_index}"
322
+ #@status_row.text = "Selected table #{tablelist.get_content()[tablelist.current_index]}"
323
+ table = "#{tablelist.get_content()[tablelist.current_index]}"
324
+ ##table = table[0] if table.class==Array ## 1.9 ???
325
+ columnlist.list_data_model.remove_all
326
+ columnlist.list_data_model.insert 0, *@db.get_metadata(table)
327
+ }
328
+ ## pressing ENTER on a table runs a query on it, no need to type and SQL
329
+ #tablelist.bind_key(13) {
330
+ tablelist.bind(:PRESS) {
331
+ @status_row.text = "Selected #{tablelist.get_content()[tablelist.current_index]}"
332
+ table = "#{tablelist.get_content()[tablelist.current_index]}"
333
+ ##table = table[0] if table.class==Array ## 1.9 ???
334
+ run_query "select * from #{table}"
335
+ }
336
+ #columnlist.bind_key(13) {
337
+ columnlist.bind(:PRESS) {
338
+ ## append column name to sqlarea if ENTER pressed
339
+ column = "#{columnlist.get_content()[columnlist.current_index]}"
340
+ sqlarea << "#{column},"
341
+ }
342
+ columnlist.bind_key(32) {
343
+ ## select row - later can press Construct button
344
+ columnlist.toggle_row_selection
345
+ column = "#{columnlist.get_content()[columnlist.current_index]}"
346
+ }
347
+ ## construct an SQL after selecting some columns in the column list
348
+ b_construct.command {
349
+ # current_index is wrong, we need selected_index
350
+ table = "#{tablelist.get_content()[tablelist.selected_index]}"
351
+ #table = table[0] if table.class==Array ## 1.9 ???
352
+ indexes = columnlist.selected_rows()
353
+ columns=[]
354
+ indexes.each do |i|
355
+ columns << columnlist.get_content()[i]
356
+ end
357
+ sql = "select #{columns.join(',')} from #{table}"
358
+ sqlarea << sql
359
+ }
360
+
361
+
362
+ @form.repaint
363
+ @window.wrefresh
364
+ Ncurses::Panel.update_panels
365
+ begin
366
+ while((ch = @window.getchar()) != ?\C-q.getbyte(0) )
367
+ break if ch == KEY_F1
368
+ s = keycode_tos ch
369
+ status_row.text = "Pressed #{ch} , #{s}. Press C-q to quit, Alt-Tab for exiting table "
370
+ @form.handle_key(ch)
371
+
372
+ @form.repaint
373
+ @window.wrefresh
374
+ end
375
+ ensure
376
+ @window.destroy if !@window.nil?
377
+ end
378
+ end
379
+ ## execute the query in the textarea
380
+ # @param [String] sql string
381
+ def run_query sql
382
+ #query = sqlarea.get_text
383
+ query = sql
384
+ begin
385
+ @content = @db.get_data query
386
+ if @content.nil?
387
+ @status_row.text = "0 rows retrieved"
388
+ return
389
+ end
390
+ #cw = @db.estimate_column_widths @atable.width, @db.columns
391
+ atable = create_table @tp, @tab_ctr #, buttrow, t_width, c
392
+ atable.set_data @content, @db.columns
393
+ cw = atable.estimate_column_widths @db.columns, @db.datatypes
394
+ atable.set_column_widths cw
395
+ rescue => exc
396
+ $log.debug(exc.backtrace.join("\n"))
397
+ alert exc.to_s
398
+ return
399
+ end
400
+ @status_row.text = "#{@content.size} rows retrieved"
401
+ atable.repaint
402
+ end
403
+ ## create a Table component for populating with data
404
+ def create_table tp, counter #, buttrow, t_width, c
405
+ table_ht = 15
406
+ atable = Table.new do
407
+ name "sqltable#{counter}"
408
+ help_text "M-Tab for next field, C-q quit"
409
+ end
410
+ atable.bind(:TABLE_TRAVERSAL_EVENT){|e| @header.text_right "Row #{e.newrow+1} of #{atable.row_count}" }
411
+ @tab_ctr += 1
412
+ tab1 = tp.add_tab "Tab&#{@tab_ctr}" , atable
413
+ return atable
414
+ end
415
+ ## create the single tabbedpane for populating with resultsets
416
+ def create_tabbed_pane form, buttrow, t_width, c
417
+ tp = RubyCurses::TabbedPane.new form do
418
+ height 16
419
+ width t_width
420
+ row buttrow +1
421
+ col c
422
+ button_type :ok
423
+ end
424
+ return tp
425
+ end
426
+ end
427
+ if $0 == __FILE__
428
+ include RubyCurses
429
+ include RubyCurses::Utils
430
+
431
+ begin
432
+ # Initialize curses
433
+ VER::start_ncurses # this is initializing colors via ColorMap.setup
434
+ #$log = Logger.new("rbc13.log")
435
+ $log = Logger.new(ENV['LOGDIR'] || "" + "rbc13.log")
436
+
437
+ $log.level = Logger::DEBUG
438
+
439
+ colors = Ncurses.COLORS
440
+ $log.debug "START #{colors} colors SQLC demo "
441
+
442
+ catch(:close) do
443
+ t = Sqlc.new
444
+ t.run
445
+ end
446
+ rescue => ex
447
+ ensure
448
+ VER::stop_ncurses
449
+ p ex if ex
450
+ p(ex.backtrace.join("\n")) if ex
451
+ $log.debug( ex) if ex
452
+ $log.debug(ex.backtrace.join("\n")) if ex
453
+ end
454
+ end