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.
- data/NOTES +68 -0
- data/README.markdown +73 -330
- data/TODO2.txt +2 -2
- data/VERSION +1 -1
- data/examples/abasiclist.rb +8 -2
- data/examples/alpmenu.rb +1 -1
- data/examples/app.rb +1 -24
- data/examples/appdirtree.rb +1 -1
- data/examples/appemail.rb +8 -14
- data/examples/appemaillb.rb +2 -2
- data/examples/appgcompose.rb +7 -5
- data/examples/common/file.rb +40 -0
- data/examples/{rmail.rb → common/rmail.rb} +0 -0
- data/examples/data/README.markdown +9 -0
- data/examples/data/brew.txt +38 -0
- data/examples/data/color.2 +37 -0
- data/examples/data/gemlist.txt +60 -0
- data/examples/data/lotr.txt +12 -0
- data/examples/data/ports.txt +136 -0
- data/examples/data/tasks.txt +27 -0
- data/examples/{todocsv.csv → data/todocsv.csv} +0 -0
- data/examples/data/unix1.txt +21 -0
- data/examples/data/unix2.txt +11 -0
- data/examples/dbdemo.rb +49 -14
- data/examples/{appgmail.rb → deprecated/appgmail.rb} +1 -1
- data/examples/{splitp.rb → deprecated/splitp.rb} +0 -0
- data/examples/{testscrolllb.rb → deprecated/testscrolllb.rb} +0 -0
- data/examples/{testscrollp.rb → deprecated/testscrollp.rb} +0 -0
- data/examples/{testscrollta.rb → deprecated/testscrollta.rb} +0 -0
- data/examples/{testscrolltable.rb → deprecated/testscrolltable.rb} +0 -0
- data/examples/{testsplit.rb → deprecated/testsplit.rb} +0 -0
- data/examples/{testsplit2.rb → deprecated/testsplit2.rb} +0 -0
- data/examples/{testsplit3.rb → deprecated/testsplit3.rb} +0 -0
- data/examples/{testsplit3_1.rb → deprecated/testsplit3_1.rb} +0 -0
- data/examples/{testsplit3a.rb → deprecated/testsplit3a.rb} +0 -0
- data/examples/{testsplit3b.rb → deprecated/testsplit3b.rb} +0 -0
- data/examples/{testsplitta.rb → deprecated/testsplitta.rb} +0 -0
- data/examples/{testsplittv.rb → deprecated/testsplittv.rb} +0 -0
- data/examples/{testsplittvv.rb → deprecated/testsplittvv.rb} +0 -0
- data/examples/{testtpane.rb → deprecated/testtpane.rb} +0 -0
- data/examples/{testtpane2.rb → deprecated/testtpane2.rb} +0 -0
- data/examples/{testtpanetable.rb → deprecated/testtpanetable.rb} +0 -0
- data/examples/dirtree.rb +17 -7
- data/examples/experimental/resultsetdemo.rb +280 -0
- data/examples/experimental/testmform.rb +35 -0
- data/examples/{testscroller.rb → experimental/testscroller.rb} +1 -19
- data/examples/experimental/teststackflow.rb +111 -0
- data/examples/menu1.rb +1 -0
- data/examples/multispl.rb +4 -4
- data/examples/newmessagebox.rb +130 -0
- data/examples/newtabbedwindow.rb +100 -0
- data/examples/newtesttabp.rb +0 -3
- data/examples/qdfilechooser.rb +0 -3
- data/examples/rfe.rb +134 -18
- data/examples/rfe_renderer.rb +48 -2
- data/examples/sqlc.rb +2 -1
- data/examples/sqlm.rb +0 -2
- data/examples/table1.rb +1 -7
- data/examples/term2.rb +4 -1
- data/examples/test1.rb +0 -5
- data/examples/test2.rb +42 -31
- data/examples/testapp2.rb +8 -1
- data/examples/testchars.rb +0 -4
- data/examples/testcombo.rb +5 -9
- data/examples/testkeypress.rb +0 -3
- data/examples/testmenu.rb +0 -4
- data/examples/testmulticomp.rb +3 -5
- data/examples/testmulticontainer.rb +94 -0
- data/examples/testtable.rb +0 -5
- data/examples/testtabp.rb +16 -18
- data/examples/testtodo.rb +1 -5
- data/examples/testwsshortcuts.rb +64 -0
- data/examples/testwsshortcuts2.rb +126 -0
- data/examples/viewtodo.rb +1 -4
- data/lib/rbcurse.rb +1 -1
- data/lib/rbcurse/app.rb +92 -69
- data/lib/rbcurse/applicationheader.rb +46 -6
- data/lib/rbcurse/celleditor.rb +1 -9
- data/lib/rbcurse/comboboxcellrenderer.rb +0 -4
- data/lib/rbcurse/common/ansiparser.rb +117 -0
- data/{examples → lib/rbcurse/common}/appmethods.rb +25 -0
- data/lib/rbcurse/common/basestack.rb +407 -0
- data/lib/rbcurse/common/bordertitle.rb +41 -0
- data/lib/rbcurse/common/chunk.rb +177 -0
- data/lib/rbcurse/common/colorparser.rb +71 -0
- data/lib/rbcurse/common/keydefs.rb +30 -0
- data/lib/rbcurse/common/widgetshortcuts.rb +302 -0
- data/lib/rbcurse/deprecated/README.markdown +12 -0
- data/lib/rbcurse/{rscrollpane.rb → deprecated/rscrollpane.rb} +0 -0
- data/lib/rbcurse/{rsplitpane.rb → deprecated/rsplitpane.rb} +0 -0
- data/lib/rbcurse/{rsplitpane2.rb → deprecated/rsplitpane2.rb} +0 -0
- data/lib/rbcurse/{rviewport.rb → deprecated/rviewport.rb} +0 -0
- data/lib/rbcurse/experimental/README.markdown +14 -0
- data/lib/rbcurse/experimental/resultsettextview.rb +585 -0
- data/lib/rbcurse/experimental/stackflow.rb +478 -0
- data/lib/rbcurse/extras/bottomline.rb +85 -16
- data/lib/rbcurse/extras/box.rb +58 -0
- data/lib/rbcurse/extras/directorylist.rb +1 -1
- data/lib/rbcurse/extras/horizlist.rb +203 -0
- data/lib/rbcurse/extras/listselectable.rb +8 -0
- data/lib/rbcurse/extras/multiform.rb +330 -0
- data/lib/rbcurse/extras/multilinelabel.rb +142 -0
- data/lib/rbcurse/extras/newmessagebox.rb +328 -0
- data/lib/rbcurse/extras/newtabbedpane.rb +612 -0
- data/lib/rbcurse/extras/newtabbedwindow.rb +68 -0
- data/lib/rbcurse/extras/padreader.rb +189 -0
- data/lib/rbcurse/extras/rcomboedit.rb +256 -0
- data/lib/rbcurse/extras/resultsetbrowser.rb +281 -0
- data/lib/rbcurse/extras/statusline.rb +44 -6
- data/lib/rbcurse/extras/tabularwidget.rb +141 -104
- data/lib/rbcurse/extras/textpad.rb +516 -0
- data/lib/rbcurse/extras/viewer.rb +2 -0
- data/lib/rbcurse/io.rb +120 -3
- data/lib/rbcurse/listcellrenderer.rb +2 -1
- data/lib/rbcurse/listkeys.rb +1 -1
- data/lib/rbcurse/listscrollable.rb +72 -7
- data/lib/rbcurse/rbasiclistbox.rb +64 -12
- data/lib/rbcurse/rchangeevent.rb +0 -1
- data/lib/rbcurse/rcombo.rb +54 -59
- data/lib/rbcurse/rcommandwindow.rb +46 -10
- data/lib/rbcurse/rcontainer.rb +415 -0
- data/lib/rbcurse/rdialogs.rb +242 -165
- data/lib/rbcurse/rinputdataevent.rb +0 -1
- data/lib/rbcurse/rlistbox.rb +19 -9
- data/lib/rbcurse/rmessagebox.rb +1 -5
- data/lib/rbcurse/rmulticontainer.rb +64 -61
- data/lib/rbcurse/rmultitextview.rb +0 -2
- data/lib/rbcurse/rpopupmenu.rb +0 -2
- data/lib/rbcurse/rscrollform.rb +61 -12
- data/lib/rbcurse/rtabbedpane.rb +89 -73
- data/lib/rbcurse/rtabbedwindow.rb +53 -211
- data/lib/rbcurse/rtable.rb +0 -2
- data/lib/rbcurse/rtextarea.rb +14 -14
- data/lib/rbcurse/rtextview.rb +165 -50
- data/lib/rbcurse/rvimsplit.rb +15 -12
- data/lib/rbcurse/rwidget.rb +404 -150
- data/lib/rbcurse/table/tablecellrenderer.rb +1 -4
- data/lib/rbcurse/table/tabledatecellrenderer.rb +0 -3
- data/lib/ver/ncurses.rb +1 -9
- data/lib/ver/rpad.rb +375 -0
- data/lib/ver/window.rb +262 -440
- 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=
|
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
|
-
|
120
|
+
DBDEMO HELP
|
114
121
|
|
115
|
-
This is some help text for
|
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 '
|
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
|
-
|
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
|
-
"
|
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
|
-
"
|
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
|
-
"
|
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(
|
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 =>
|
388
|
-
tarea = textarea :name => 'tarea', :height =>
|
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
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
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 =
|
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
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
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
|