rbcurse-core 0.0.0

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 (94) hide show
  1. data/README.md +69 -0
  2. data/VERSION +1 -0
  3. data/examples/abasiclist.rb +151 -0
  4. data/examples/alpmenu.rb +46 -0
  5. data/examples/app.sample +17 -0
  6. data/examples/atree.rb +100 -0
  7. data/examples/common/file.rb +45 -0
  8. data/examples/data/README.markdown +9 -0
  9. data/examples/data/brew.txt +38 -0
  10. data/examples/data/color.2 +37 -0
  11. data/examples/data/gemlist.txt +60 -0
  12. data/examples/data/lotr.txt +12 -0
  13. data/examples/data/ports.txt +136 -0
  14. data/examples/data/table.txt +37 -0
  15. data/examples/data/tasks.csv +88 -0
  16. data/examples/data/tasks.txt +27 -0
  17. data/examples/data/todo.txt +10 -0
  18. data/examples/data/todocsv.csv +28 -0
  19. data/examples/data/unix1.txt +21 -0
  20. data/examples/data/unix2.txt +11 -0
  21. data/examples/dbdemo.rb +487 -0
  22. data/examples/dirtree.rb +90 -0
  23. data/examples/newtabbedwindow.rb +100 -0
  24. data/examples/newtesttabp.rb +92 -0
  25. data/examples/tabular.rb +132 -0
  26. data/examples/tasks.rb +167 -0
  27. data/examples/term2.rb +83 -0
  28. data/examples/testkeypress.rb +72 -0
  29. data/examples/testlistbox.rb +158 -0
  30. data/examples/testmessagebox.rb +140 -0
  31. data/examples/testree.rb +106 -0
  32. data/examples/testwsshortcuts.rb +66 -0
  33. data/examples/testwsshortcuts2.rb +127 -0
  34. data/lib/rbcurse.rb +8 -0
  35. data/lib/rbcurse/core/docs/index.txt +73 -0
  36. data/lib/rbcurse/core/include/action.rb +40 -0
  37. data/lib/rbcurse/core/include/appmethods.rb +112 -0
  38. data/lib/rbcurse/core/include/bordertitle.rb +41 -0
  39. data/lib/rbcurse/core/include/chunk.rb +182 -0
  40. data/lib/rbcurse/core/include/io.rb +953 -0
  41. data/lib/rbcurse/core/include/listcellrenderer.rb +140 -0
  42. data/lib/rbcurse/core/include/listeditable.rb +317 -0
  43. data/lib/rbcurse/core/include/listscrollable.rb +590 -0
  44. data/lib/rbcurse/core/include/listselectable.rb +264 -0
  45. data/lib/rbcurse/core/include/multibuffer.rb +83 -0
  46. data/lib/rbcurse/core/include/orderedhash.rb +77 -0
  47. data/lib/rbcurse/core/include/ractionevent.rb +67 -0
  48. data/lib/rbcurse/core/include/rchangeevent.rb +27 -0
  49. data/lib/rbcurse/core/include/rhistory.rb +62 -0
  50. data/lib/rbcurse/core/include/rinputdataevent.rb +47 -0
  51. data/lib/rbcurse/core/include/vieditable.rb +170 -0
  52. data/lib/rbcurse/core/system/colormap.rb +163 -0
  53. data/lib/rbcurse/core/system/keyboard.rb +150 -0
  54. data/lib/rbcurse/core/system/keydefs.rb +30 -0
  55. data/lib/rbcurse/core/system/ncurses.rb +218 -0
  56. data/lib/rbcurse/core/system/panel.rb +162 -0
  57. data/lib/rbcurse/core/system/window.rb +901 -0
  58. data/lib/rbcurse/core/util/ansiparser.rb +117 -0
  59. data/lib/rbcurse/core/util/app.rb +1235 -0
  60. data/lib/rbcurse/core/util/basestack.rb +407 -0
  61. data/lib/rbcurse/core/util/bottomline.rb +1850 -0
  62. data/lib/rbcurse/core/util/colorparser.rb +71 -0
  63. data/lib/rbcurse/core/util/focusmanager.rb +31 -0
  64. data/lib/rbcurse/core/util/padreader.rb +189 -0
  65. data/lib/rbcurse/core/util/rcommandwindow.rb +587 -0
  66. data/lib/rbcurse/core/util/rdialogs.rb +619 -0
  67. data/lib/rbcurse/core/util/viewer.rb +149 -0
  68. data/lib/rbcurse/core/util/widgetshortcuts.rb +505 -0
  69. data/lib/rbcurse/core/widgets/applicationheader.rb +102 -0
  70. data/lib/rbcurse/core/widgets/box.rb +58 -0
  71. data/lib/rbcurse/core/widgets/divider.rb +310 -0
  72. data/lib/rbcurse/core/widgets/keylabelprinter.rb +178 -0
  73. data/lib/rbcurse/core/widgets/rcombo.rb +238 -0
  74. data/lib/rbcurse/core/widgets/rcontainer.rb +415 -0
  75. data/lib/rbcurse/core/widgets/rlink.rb +30 -0
  76. data/lib/rbcurse/core/widgets/rlist.rb +723 -0
  77. data/lib/rbcurse/core/widgets/rmenu.rb +939 -0
  78. data/lib/rbcurse/core/widgets/rmenulink.rb +22 -0
  79. data/lib/rbcurse/core/widgets/rmessagebox.rb +373 -0
  80. data/lib/rbcurse/core/widgets/rprogress.rb +118 -0
  81. data/lib/rbcurse/core/widgets/rtabbedpane.rb +615 -0
  82. data/lib/rbcurse/core/widgets/rtabbedwindow.rb +68 -0
  83. data/lib/rbcurse/core/widgets/rtextarea.rb +920 -0
  84. data/lib/rbcurse/core/widgets/rtextview.rb +780 -0
  85. data/lib/rbcurse/core/widgets/rtree.rb +787 -0
  86. data/lib/rbcurse/core/widgets/rwidget.rb +3040 -0
  87. data/lib/rbcurse/core/widgets/scrollbar.rb +143 -0
  88. data/lib/rbcurse/core/widgets/statusline.rb +94 -0
  89. data/lib/rbcurse/core/widgets/tabular.rb +264 -0
  90. data/lib/rbcurse/core/widgets/tabularwidget.rb +1211 -0
  91. data/lib/rbcurse/core/widgets/textpad.rb +516 -0
  92. data/lib/rbcurse/core/widgets/tree/treecellrenderer.rb +150 -0
  93. data/lib/rbcurse/core/widgets/tree/treemodel.rb +428 -0
  94. metadata +156 -0
@@ -0,0 +1,10 @@
1
+ 2. Show key mappings to user
2
+ 3. how to override +- * a and others for listbox - need to call before super()
3
+ 4. app to contain window close and confirm close
4
+ 4. when sorting cursor on old row but curr changed
5
+ 5. app needs to pass up exceptions to user app
6
+ 5. test out vieditable and listeditable with core
7
+ .3. Make keylabels more rubyesque - later
8
+ x5. convert testlistbox to core
9
+ x5. messagebox default button - done but current button should show default char
10
+ x5. messagebox to catch YN keys also
@@ -0,0 +1,28 @@
1
+ FIXME,MSGBOX,5,Confirm dialog: box vertical line overwritten in 2 spots,TODO
2
+ FIXME,MSGBOX,5,Confirm dialog: use normal key as hotkey also,TODO,Tue Jan 20 11:44:49 +0530 2009
3
+ FIXME,MSGBOX,5,Confirm dialog: arrow keys not navigating anylonger,TODO,Tue Jan 20 11:45:27 +0530 2009
4
+ FIXME,GEN,9,Message Box sizing,TODO,Thu Jan 22 20:39:21 +0530 2009
5
+ DONE,LIST,5,case insensitive char search in list and combo,TESTED,Sat Feb 21 20:43:05 +0530 2009
6
+ DONE,TABLE,5,increase the maxlen of this field please. Let us see how it goes.,TESTED
7
+ DONE,TABLE,5,Can we disable down arrow in Chkbox in table?,TESTED,Mon Jan 19 00:00:00 +0530 2009
8
+ DONE,TABLE,0,editing on enter,TESTED,Mon Jan 19 01:37:00 +0530 2009
9
+ DONE,TABLE,5,cell editors pcol is not being reset each time,TESTED,Mon Jan 19 17:47:00 +0530 2009
10
+ DONE,TABLE,5,Use TAB for intercell navig. use M-TAB for next f,TESTED,Tue Jan 20 00:38:19 +0530 2009
11
+ DONE,TABLE,5,Searching,TESTED,Sat Feb 21 20:42:10 +0530 2009
12
+ DONE,TABLE,3,Columns editable or not,TESTED,Sat Feb 21 20:43:10 +0530 2009
13
+ DONE,TABLE,1,Any way to start a table with no data and pop late,TODO,Sat Feb 21 20:43:33 +0530 2009
14
+ DONE,GEN,5,Make widget of Keylabelprinter,TESTED,Tue Jan 20 00:38:43 +0530 2009
15
+ DONE,GEN,5,Added Action class shared by Button Menuitem ,TESTED,Thu Jan 22 18:08:28 +0530 2009
16
+ DONE,GEN,5,Added PopupMenu 2009-01-22 18:09 ,TESTED,Thu Jan 22 18:09:34 +0530 2009
17
+ DONE,LIST,0,call on_enter and on_leave of component,TOTEST,Sun Feb 22 12:19:38 +0530 2009
18
+ DONE,FIELD,5,Field: OVERWRITE Mode,TESTED,2010-09-13 11:24:35 +0530
19
+ DONE,GEN,5,"Modified should check if value changed, not UP etc",TOTEST,2010-09-13 11:25:18 +0530
20
+ TODO,TABLE,1,table.set_data should check if models already created.,TODO
21
+ TODO,TABLE,5,"Set column_class in TableColumn, to avoid hassles",TODO
22
+ TODO,TABLE,2,Table sorting and filtering is required - using VIEW,TODO
23
+ TODO,TABLE,5,Table height and col widths auto sizing or FILLING extra space.,TODO
24
+ TODO,TEXTAREA,9,"Textarea: wrap options NONE, COLUMN",TODO,Tue Jan 20 01:04:15 +0530 2009
25
+ TODO,GEN,5,Give a decent FileChooser and FileSaver,TODO
26
+ TODO,GEN,5,Focus Traversable vs focusable,TODO
27
+ TODO,GEN,5,Action class: fire event for listeners,TODO,Thu Jan 22 20:09:50 +0530 2009
28
+ TODO,FIELD,5,Field: Auto-skip when reaching end of maxlen,TODO
@@ -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
+
@@ -0,0 +1,487 @@
1
+ require 'rbcurse/core/util/app'
2
+ require 'sqlite3'
3
+ #require 'rbcurse/experimental/resultsettextview.rb'
4
+ #require 'rbcurse/experimental/widgets/undomanager'
5
+
6
+ # @return array of table names from selected db file
7
+ def get_table_names
8
+ raise "No database file selected." unless $current_db
9
+
10
+ $tables = get_data "select name from sqlite_master"
11
+ $tables.collect!{|x| x[0] } ## 1.9 hack, but will it run on 1.8 ??
12
+ $tables
13
+ end
14
+ def get_column_names tbname
15
+ get_metadata tbname
16
+ end
17
+ def connect dbname
18
+ $log.debug "XXX: CONNECT got #{dbname} "
19
+ $current_db = dbname
20
+ $db = SQLite3::Database.new(dbname)
21
+
22
+ return $db
23
+ end
24
+ def get_data sql
25
+ $log.debug "SQL: #{sql} "
26
+ $columns, *rows = $db.execute2(sql)
27
+ $log.debug "XXX COLUMNS #{sql} "
28
+ content = rows
29
+ return nil if content.nil? or content[0].nil?
30
+ $datatypes = content[0].types #if @datatypes.nil?
31
+ return content
32
+ end
33
+ def get_metadata table
34
+ get_data "select * from #{table} limit 1"
35
+ #$columns.collect!{|x| x[0] } ## 1.9 hack, but will it run on 1.8 ??
36
+ return $columns
37
+ end
38
+ #
39
+ # creates a popup for selection given the data, and executes given block with
40
+ # following return value.
41
+ # @return [String] if mode is :single
42
+ # @return [Array] if mode is :multiple
43
+ #
44
+ def create_popup array, selection_mode=:single, &blk
45
+ #raise "no block given " unless block_given?
46
+ listconfig = {'bgcolor' => 'blue', 'color' => 'white'}
47
+ listconfig[:selection_mode] = selection_mode
48
+ ix = popuplist array, listconfig
49
+ if ix
50
+ if selection_mode == :single
51
+ value = array[ix]
52
+ blk.call value
53
+ else
54
+ #values = array.select {|v| ix.include? v}
55
+ values = []
56
+ array.each_with_index { |v, i| values << v if ix.include? i }
57
+ blk.call(values)
58
+ end
59
+ end
60
+ end
61
+
62
+ def view_data fields='*', name
63
+ stmt = "select #{fields} from #{name}"
64
+ stmt << $where_string if $where_string
65
+ stmt << $order_string if $order_string
66
+ view_sql stmt
67
+ @form.by_name['tarea'] << stmt if @form # nil when called from menu
68
+ end
69
+ def view_sql stmt
70
+ begin
71
+ content = get_data stmt
72
+ if content.nil?
73
+ else
74
+ require 'rbcurse/core/widgets/tabular'
75
+ t = Tabular.new do |t|
76
+ t.headings = $columns
77
+ t.data=content
78
+ end
79
+ view t.render
80
+ end
81
+ rescue => err
82
+ $log.error err.to_s
83
+ $log.error(err.backtrace.join("\n"))
84
+ alert err.to_s
85
+ end
86
+ end
87
+
88
+ App.new do
89
+ header = app_header "rbcurse #{Rbcurse::VERSION}", :text_center => "Database Demo", :text_right =>"enabled"
90
+ form = @form
91
+ mylabel = "a field"
92
+ $catch_alt_digits = true # use M-1..9 in textarea
93
+ $current_table = nil
94
+ $current_db = nil # "testd.db"
95
+ connect $current_db if $current_db
96
+ def which_field
97
+ alert "curent field is #{form.get_current_field} "
98
+ end
99
+
100
+ def get_commands
101
+ %w{ which_field }
102
+ end
103
+ def help_text
104
+ <<-eos
105
+ DBDEMO HELP
106
+
107
+ This is some help text for dbdemo.
108
+ We are testing out this feature.
109
+
110
+ Alt-d - Select a database
111
+ <Enter> on a table, view data (q to close window)
112
+ <Space> on a table, display columns in lower list
113
+
114
+ COLUMN LIST KEYS
115
+ <Space> on a column for multiple select
116
+ <Ctrl-Space> on a column for range select/deselect from previous selection
117
+ <Enter> on column table to view data for selected columns
118
+ u unselect all
119
+ a select all
120
+ * invert selection
121
+ F4 View data for selected table (or columns if selected)
122
+
123
+ q or C-q Close the data window that comes on Enter or F4
124
+
125
+ Alt-x - Command mode (<tab> to see commands and select)
126
+ : - Command mode
127
+ Alt-z - Commands in TextArea
128
+
129
+ DB BROWSER KEYS
130
+
131
+ , Prev row (mnemonic <)
132
+ . Next row (mnemonic >)
133
+ < First row
134
+ > Last row
135
+
136
+ F10 - Quit application
137
+
138
+
139
+
140
+ -----------------------------------------------------------------------
141
+ Hope you enjoyed this help.
142
+ eos
143
+ end
144
+ def ask_databases
145
+ names = Dir.glob("*.{sqlite,db}")
146
+ if names
147
+ ix = popuplist( names )
148
+ if ix
149
+ value = names[ix]
150
+ connect(value);
151
+ @form.by_name["tlist"].list(get_table_names)
152
+ end
153
+
154
+ else
155
+ alert "Can't find a .db or .sqlite file"
156
+ end
157
+ end
158
+ # TODO accelerators and
159
+ # getting a handle for later use
160
+ mb = menubar do
161
+ keep_visible true
162
+ #@toggle_key=KEY_F2
163
+ menu "File" do
164
+ item "Open", "O" do
165
+ accelerator "Ctrl-O"
166
+ command do
167
+ alert "HA!! you wanted to open a file?"
168
+ end
169
+ end
170
+ menu "Database" do
171
+ item_list do
172
+ Dir.glob("**/*.{sqlite,db}")
173
+ end
174
+ command do |menuitem, text|
175
+ connect text
176
+ form.by_name["tlist"].list(get_table_names)
177
+ end
178
+ end
179
+ menu "Tables" do
180
+ item_list do
181
+ if $current_db
182
+ get_table_names
183
+ end
184
+ end
185
+ command do |menuitem, text|
186
+ $current_table = text
187
+ #alert(get_column_names(text).join(", "))
188
+ create_popup(get_column_names(text), :multiple) { |value| view_data( value.join(","), text) }
189
+ end
190
+ end
191
+ item "New", "N"
192
+ separator
193
+ item "Exit", "x" do
194
+ command do
195
+ throw(:close)
196
+ end
197
+ end
198
+ item "Cancel Menu" do
199
+ accelerator "Ctrl-g"
200
+ end
201
+
202
+ end # menu
203
+ menu "Window" do
204
+ item "Tile", "T"
205
+ menu "Find" do
206
+ item "More", "M"
207
+ $x = item "Less", "L" do
208
+ #accelerator "Ctrl-X"
209
+ command do
210
+ alert "You clickses on Less"
211
+ end
212
+ end
213
+ menu "Size" do
214
+ item "Zoom", "Z"
215
+ item "Maximize", "X"
216
+ item "Minimize", "N"
217
+ end
218
+ end
219
+ end
220
+ menu "Others" do
221
+ require 'rbcurse/core/include/appmethods.rb'
222
+ item "Shell Output" do
223
+ command { shell_output }
224
+ end
225
+ item "Suspend" do
226
+ command { suspend }
227
+ end
228
+ end
229
+ end # menubar
230
+ mb.toggle_key = FFI::NCurses::KEY_F2
231
+ mb.color = :white
232
+ mb.bgcolor = :blue
233
+ @form.set_menu_bar mb
234
+ tv = nil
235
+ flow :margin_top => 1 do
236
+ col1w = 20
237
+ stack :width_pc => 20 do
238
+ text = "No tables"
239
+ if !$current_db
240
+ text = "Select DB first. Press Alt-D"
241
+ end
242
+ tlist = basiclist :name => "tlist", :list => [text], :title => "Tables", :height => 10,
243
+ :selected_color => 'cyan', :selected_bgcolor => 'black' , :selected_attr => Ncurses::A_REVERSE,
244
+ :help_text => "Enter to View complete table, Space to select table and view columns",
245
+ :should_show_focus => true,
246
+ :selection_mode => :single
247
+ tlist.bind(:PRESS) do |eve|
248
+ if $current_db
249
+ # get data of table
250
+ view_data eve.text
251
+ #tv.sqlite $current_db, eve.text, "select * from #{eve.text} " # TODO in core
252
+ else
253
+ ask_databases
254
+ end
255
+ end
256
+ #tlist.bind(:ENTER_ROW) do |eve|
257
+ # too much confusion between selected and focussed row
258
+ #$current_table = eve.text if $db
259
+ #end
260
+ clist = basiclist :name => "clist", :list => ["No columns"], :title => "Columns", :height => 14,
261
+ :selection_mode => :multiple,
262
+ :selected_color => 'cyan', :selected_bgcolor => 'black' , :selected_attr => Ncurses::A_REVERSE,
263
+ :help_text => "Enter to View selected fields, Space to select columns, w - where, o-order"
264
+ tlist.bind(:LIST_SELECTION_EVENT) do |eve|
265
+ $selected_table = eve.source[eve.firstrow]
266
+ $current_table = $selected_table
267
+ clist.data = get_column_names $selected_table
268
+ end
269
+ clist.bind(:PRESS) do |eve|
270
+ # get data of table
271
+ if $selected_table
272
+ cols = "*"
273
+ c = clist.get_selected_values
274
+ unless c.empty?
275
+ cols = c.join(",")
276
+ end
277
+ view_data cols, $selected_table
278
+ else
279
+ alert "Select a table first."
280
+ end
281
+ end
282
+ clist.bind_key('w') {
283
+ c = clist.current_value
284
+ $where_columns ||= []
285
+ hist = ["#{c} = "]
286
+ w = ask("(UP arrow to edit) where "){ |q| q.default = "#{c} = "; q.history = hist }
287
+ $where_columns << w if w
288
+ message "where: #{$where_columns.last}. Press F4 when done"
289
+ $log.debug "XXX: WHERE: #{$where_columns} "
290
+ }
291
+ clist.bind_key('o') {
292
+ c = clist.current_value
293
+ $order_columns ||= []
294
+ $order_columns << c if c
295
+ message "order (asc): #{$order_columns.last}. Press F4 when done"
296
+ $log.debug "XXX: ORDER: #{$order_columns} "
297
+ }
298
+ clist.bind_key('O') {
299
+ c = clist.current_value
300
+ $order_columns ||= []
301
+ $order_columns << " #{c} desc " if c
302
+ message "order: #{$order_columns.last}"
303
+ $log.debug "XXX: ORDER: #{$order_columns}. Press F4 when done"
304
+ }
305
+ @statusline = status_line
306
+ #wg = get_color($datacolor, 'white','green')
307
+ #wb = get_color($datacolor, 'white','blue')
308
+ @statusline.command {
309
+ # trying this out. If you want a persistent message that remains till the next on
310
+ # then send it in as $status_message
311
+ text = $status_message.value || ""
312
+ if !$current_db
313
+ #"[%-s] %s" % [ "Select a Database", text]
314
+ "[%-s] %s" % [ "#[bg=red,fg=yellow]Select a Database#[end]", text]
315
+ #[ [nil, "%-22s" % Time.now, nil], [$errorcolor, " [Select a Database ]", FFI::NCurses::A_BOLD], [nil, text, nil] ]
316
+ elsif !$current_table
317
+ "[DB: #[fg=white,bg=blue]%-s#[end] | %-s ] %s" % [ $current_db || "None", $current_table || "#[bg=red,fg=yellow]Select a table#[end]", text]
318
+ #[ [nil, "%-22s [DB: %-s | " % [Time.now, $current_db || "None" ],nil], [$errorcolor, " Select a Table ]", FFI::NCurses::A_BOLD], [nil, text, nil] ]
319
+ else
320
+ "DB: #[fg=white,bg=green,bold]%-s#[end] | #[bold]%-s#[end] ] %s" % [ $current_db || "None", $current_table || "----", text]
321
+ #[ [nil, "%-22s [DB: " % Time.now, nil], [wb, " #{$current_db} ", FFI::NCurses::A_BOLD],
322
+ #[wg, $current_table || "----", FFI::NCurses::A_BOLD], [nil, text, nil] ]
323
+ end
324
+ }
325
+ @adock = nil
326
+ keyarray = [
327
+ ["F1" , "Help"], ["F10" , "Exit"],
328
+ ["F2", "Menu"], ["F4", "View"],
329
+ ["M-d", "Datebase"], ["M-t", "Table"],
330
+ ["M-x", "Command"], nil
331
+ ]
332
+ tlist_keyarray = keyarray + [ ["Sp", "Select"], nil, ["Enter","View"] ]
333
+
334
+ clist_keyarray = keyarray + [ ["Sp", "Select"], ["C-sp", "Range Sel"],
335
+ ["Enter","View"], ['w', 'where'],
336
+ ["o","order by"], ['O', 'order desc']
337
+ ]
338
+ tarea_keyarray = keyarray + [ ["M-z", "Commands"], nil ]
339
+ #tarea_sub_keyarray = [ ["r", "Run"], ["c", "clear"], ["w","Save"], ["a", "Append next"],
340
+ #["y", "Yank"], ["Y", "yank pop"] ]
341
+ tarea_sub_keyarray = [ ["r", "Run"], ["c", "clear"], ["w","Kill Ring Save (M-w)"], ["a", "Append Next"],
342
+ ["y", "Yank (C-y)"], ["Y", "yank pop (M-y)"],
343
+ ["u", "Undo (C-_)"], ["R", "Redo (C-r)"],
344
+ ]
345
+
346
+ gw = get_color($reversecolor, 'green', 'black')
347
+ @adock = dock keyarray, { :row => Ncurses.LINES-2, :footer_color_pair => $datacolor,
348
+ :footer_mnemonic_color_pair => gw }
349
+ @adock.set_key_labels tlist_keyarray, :tables
350
+ @adock.set_key_labels clist_keyarray, :columns
351
+ @adock.set_key_labels tarea_sub_keyarray, :tarea_sub
352
+ @adock.set_key_labels tarea_keyarray, :tarea
353
+ tlist.bind(:ENTER) { @adock.mode :tables }
354
+ clist.bind(:ENTER) { @adock.mode :columns }
355
+
356
+ reduce = lambda { |obj|
357
+ obj.height -= 1 if obj.height > 3
358
+ }
359
+ increase = lambda { |obj|
360
+ obj.height += 1 if obj.height + obj.row < Ncurses.LINES-2
361
+ }
362
+ _lower = lambda { |obj|
363
+ obj.row += 1 if obj.height + obj.row < Ncurses.LINES-2
364
+ }
365
+ _raise = lambda { |obj|
366
+ obj.row -= 1 if obj.row > 2
367
+ }
368
+ [clist, tlist].each do |o|
369
+ o.bind_key([?\C-x, ?-]){ |o| reduce.call(o) }
370
+ o.bind_key([?\C-x, ?+]){ |o| increase.call(o) }
371
+ o.bind_key([?\C-x, ?v]){ |o| _lower.call(o) }
372
+ o.bind_key([?\C-x, ?6]){ |o| _raise.call(o) }
373
+ end
374
+
375
+
376
+ @form.bind_key([?q,?q]) { throw :close }
377
+ @form.bind_key(?\M-t) do
378
+ if $current_db.nil?
379
+ alert "Please select database first"
380
+ else
381
+ create_popup( get_table_names,:single) {|value| $selected_table = $current_table = value}
382
+ end
383
+ end
384
+ @form.bind_key(?\M-d) do
385
+ ask_databases
386
+ end
387
+ @form.bind_key(FFI::NCurses::KEY_F4) do
388
+ $where_string = nil
389
+ $order_string = nil
390
+ if $where_columns
391
+ $where_string = " where " + $where_columns.join(" and ")
392
+ end
393
+ if $order_columns
394
+ $order_string = " order by " + $order_columns.join(" , ")
395
+ end
396
+ # mismatch between current and selected table
397
+ if $current_table
398
+ cols = "*"
399
+ c = clist.get_selected_values
400
+ unless c.empty?
401
+ cols = c.join(",")
402
+ end
403
+ view_data cols, $current_table
404
+ else
405
+ alert "Select a table first."
406
+ end
407
+ end
408
+ end # stack
409
+ stack :width_pc => 80 do
410
+ tarea = textarea :name => 'tarea', :height => 5, :title => 'Sql Statement'
411
+ #undom = SimpleUndo.new tarea
412
+ tarea.bind_key(Ncurses::KEY_F4) do
413
+ text = tarea.get_text
414
+ if text == ""
415
+ alert "Please enter a query and then hit F4. Or press F4 over column list"
416
+ else
417
+ view_sql tarea.get_text
418
+ end
419
+ end
420
+ tarea.bind(:ENTER) { @adock.mode :tarea }
421
+ tarea.bind_key(?\M-z){
422
+
423
+ hash = { 'c' => lambda{ tarea.remove_all },
424
+ 'w' => lambda{ tarea.kill_ring_save },
425
+ 'a' => lambda{ tarea.append_next_kill },
426
+ 'y' => lambda{ tarea.yank },
427
+ 'Y' => lambda{ tarea.yank_pop },
428
+ 'r' => lambda{ view_sql tarea.get_text },
429
+ 'u' => lambda{ tarea.undo },
430
+ 'R' => lambda{ tarea.redo },
431
+ }
432
+
433
+
434
+ @adock.mode :tarea_sub
435
+ @adock.repaint
436
+ keys = @adock.get_current_keys
437
+ while((ch = @window.getchar()) != ?\C-c.getbyte(0) )
438
+ if ch < 33 || ch > 126
439
+ Ncurses.beep
440
+ elsif !keys.include?(ch.chr)
441
+ Ncurses.beep
442
+ else
443
+ hash.fetch(ch.chr).call
444
+ #opt_file ch.chr
445
+ break
446
+ end
447
+ end
448
+ @adock.mode :normal
449
+ } # M-z
450
+ flow do
451
+ #button_row = 17
452
+ button "Save" do
453
+ @cmd_history ||= []
454
+ filename = ask("File to append contents to: ") { |q| q.default = @oldfilename; q.history = @cmd_history }
455
+
456
+ if filename
457
+ str = tarea.get_text
458
+ File.open(filename, 'a') {|f| f.write(str) }
459
+ @oldfilename = filename
460
+ @cmd_history << filename unless @cmd_history.include? filename
461
+
462
+ message "Appended data to #{filename}"
463
+ else
464
+ message "Aborted operation"
465
+ end
466
+ hide_bottomline
467
+ end
468
+ button "Read" do
469
+ filter = "*"
470
+ str = choose filter, :title => "Files", :prompt => "Choose a file: "
471
+ begin
472
+ tarea.set_content(str)
473
+ message "Read content from #{str} "
474
+ rescue => err
475
+ say_with_pause "No file named: #{str}: #{err.to_s} "
476
+ end
477
+ end
478
+ #ok_button = button( [button_row,30], "OK", {:mnemonic => 'O'}) do
479
+ #end
480
+ end
481
+ blank
482
+ #tv = RubyCurses::ResultsetTextView.new @form, :row => 1, :col => 1, :width => 50, :height => 16
483
+ #tv = resultsettextview :name => 'resultset', :height => 18 , :title => 'DB Browser', :print_footer => true
484
+
485
+ end
486
+ end
487
+ end # app