rbcurse 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (55) hide show
  1. data/CHANGELOG +1570 -0
  2. data/History.txt +6 -0
  3. data/Manifest.txt +54 -0
  4. data/README.txt +304 -0
  5. data/Rakefile +28 -0
  6. data/examples/qdfilechooser.rb +68 -0
  7. data/examples/rfe.rb +853 -0
  8. data/examples/rfe_renderer.rb +69 -0
  9. data/examples/test1.rb +242 -0
  10. data/examples/test2.rb +498 -0
  11. data/examples/testcombo.rb +95 -0
  12. data/examples/testkeypress.rb +61 -0
  13. data/examples/testmenu.rb +105 -0
  14. data/examples/testtable.rb +266 -0
  15. data/examples/testtabp.rb +106 -0
  16. data/examples/testtodo.rb +532 -0
  17. data/examples/viewtodo.rb +512 -0
  18. data/lib/rbcurse/action.rb +31 -0
  19. data/lib/rbcurse/applicationheader.rb +57 -0
  20. data/lib/rbcurse/celleditor.rb +120 -0
  21. data/lib/rbcurse/checkboxcellrenderer.rb +69 -0
  22. data/lib/rbcurse/colormap.rb +133 -0
  23. data/lib/rbcurse/comboboxcellrenderer.rb +45 -0
  24. data/lib/rbcurse/defaultlistselectionmodel.rb +49 -0
  25. data/lib/rbcurse/keylabelprinter.rb +143 -0
  26. data/lib/rbcurse/listcellrenderer.rb +99 -0
  27. data/lib/rbcurse/listkeys.rb +33 -0
  28. data/lib/rbcurse/listscrollable.rb +216 -0
  29. data/lib/rbcurse/listselectable.rb +67 -0
  30. data/lib/rbcurse/mapper.rb +108 -0
  31. data/lib/rbcurse/orderedhash.rb +77 -0
  32. data/lib/rbcurse/rcombo.rb +243 -0
  33. data/lib/rbcurse/rdialogs.rb +183 -0
  34. data/lib/rbcurse/rform.rb +845 -0
  35. data/lib/rbcurse/rinputdataevent.rb +36 -0
  36. data/lib/rbcurse/rlistbox.rb +804 -0
  37. data/lib/rbcurse/rmenu.rb +666 -0
  38. data/lib/rbcurse/rmessagebox.rb +325 -0
  39. data/lib/rbcurse/rpopupmenu.rb +754 -0
  40. data/lib/rbcurse/rtabbedpane.rb +259 -0
  41. data/lib/rbcurse/rtable.rb +1296 -0
  42. data/lib/rbcurse/rtextarea.rb +673 -0
  43. data/lib/rbcurse/rtextview.rb +335 -0
  44. data/lib/rbcurse/rwidget.rb +1731 -0
  45. data/lib/rbcurse/scrollable.rb +301 -0
  46. data/lib/rbcurse/selectable.rb +94 -0
  47. data/lib/rbcurse/table/tablecellrenderer.rb +85 -0
  48. data/lib/rbcurse/table/tabledatecellrenderer.rb +102 -0
  49. data/lib/rbcurse.rb +7 -0
  50. data/lib/ver/keyboard.rb +150 -0
  51. data/lib/ver/keyboard2.rb +170 -0
  52. data/lib/ver/ncurses.rb +102 -0
  53. data/lib/ver/window.rb +369 -0
  54. data/test/test_rbcurse.rb +0 -0
  55. metadata +118 -0
data/examples/rfe.rb ADDED
@@ -0,0 +1,853 @@
1
+ require 'rubygems'
2
+ require 'ncurses'
3
+ require 'logger'
4
+ require 'rbcurse'
5
+ require 'rbcurse/rcombo'
6
+ require 'rbcurse/rlistbox'
7
+ require 'rfe_renderer'
8
+ #require 'lib/rbcurse/table/tablecellrenderer'
9
+ require 'rbcurse/keylabelprinter'
10
+ require 'rbcurse/applicationheader'
11
+ require 'rbcurse/action'
12
+ require 'fileutils'
13
+ #$LOAD_PATH << "/Users/rahul/work/projects/rbcurse/"
14
+
15
+ # TODO
16
+ # operations on selected files: move, delete, zip
17
+ # This class represents the finder pane. There are 2
18
+ # on this sample app
19
+ class FileExplorer
20
+ include FileUtils
21
+ attr_reader :wdir
22
+ attr_reader :list # listbox
23
+ attr_reader :dir
24
+ attr_reader :prev_dirs
25
+ attr_reader :other_list # the opposite list
26
+ attr_reader :entries # avoid, can be outdated
27
+ attr_accessor :filter_pattern
28
+
29
+ def initialize form, rfe, row, col, height, width
30
+ @form = form
31
+ @rfe = rfe
32
+ @row, @col, @ht, @wid = row, col, height, width
33
+ @dir = Dir.new(Dir.getwd)
34
+ @wdir = @dir.path
35
+ @filter_pattern = '*'
36
+ @prev_dirs=[]
37
+ end
38
+ def title str
39
+ @list.title = str
40
+ end
41
+ def selected_color
42
+ @list.selected_color
43
+ end
44
+ def selected_bgcolor
45
+ @list.selected_bgcolor
46
+ end
47
+
48
+ # changes to given dir
49
+ # ensure that path is provided since other list
50
+ # may have cd'd elsewhere
51
+ def change_dir adir
52
+ list = @list
53
+ begin
54
+ #dir = File.expand_path dir
55
+ #cd "#{@dir.path}/#{adir}"
56
+ cd adir
57
+ list.title = pwd()
58
+ @dir = Dir.new(Dir.getwd)
59
+ @wdir = @dir.path
60
+ @prev_dirs << @wdir
61
+ rescan
62
+ rescue => err
63
+ @rfe.status_row.text = err.to_s
64
+ end
65
+ end
66
+ def goto_previous_dir
67
+ d = @prev_dirs.pop
68
+ if !d.nil? and d == @wdir
69
+ d = @prev_dirs.pop
70
+ end
71
+ change_dir d unless d.nil?
72
+ end
73
+ def filter list
74
+ list.delete_if { |f|
75
+ !File.directory? @wdir +"/"+ f and !File.fnmatch?(@filter_pattern, f)
76
+ }
77
+ #$log.debug " FILTER CALLED AFTER #{list.size}, #{list.entries}"
78
+ end
79
+ def rescan
80
+ flist = @dir.entries
81
+ flist.shift
82
+ #populate @entries
83
+ populate flist
84
+ end
85
+ def populate flist
86
+ #fl << format_string("..", nil)
87
+ #fl = []
88
+ #flist.each {|f| ff = "#{@wdir}/#{f}"; stat = File.stat(ff)
89
+ # fl << format_string(f, stat)
90
+ #}
91
+ filter(flist) if @filter_pattern != '*'
92
+ @entries = flist
93
+ list.list_data_model.remove_all
94
+ #list.list_data_model.insert 0, *fl
95
+ list.list_data_model.insert 0, *flist
96
+ end
97
+ def sort key, reverse=false
98
+ # remove parent before sorting, keep at top
99
+ first = @entries.delete_at(0) if @entries[0]==".."
100
+ key ||= @sort_key
101
+ cdir=cur_dir()+"/"
102
+ case key
103
+ when :size
104
+ @entries.sort! {|x,y| xs = File.stat(cdir+x); ys = File.stat(cdir+y);
105
+ if reverse
106
+ xs.size <=> ys.size
107
+ else
108
+ ys.size <=> xs.size
109
+ end
110
+ }
111
+ when :mtime
112
+ @entries.sort! {|x,y| xs = File.stat(cdir+x); ys = File.stat(cdir+y);
113
+ if reverse
114
+ xs.mtime <=> ys.mtime
115
+ else
116
+ ys.mtime <=> xs.mtime
117
+ end
118
+ }
119
+ when :atime
120
+ @entries.sort! {|x,y| xs = File.stat(cdir+x); ys = File.stat(cdir+y);
121
+ if reverse
122
+ xs.atime <=> ys.atime
123
+ else
124
+ ys.atime <=> xs.atime
125
+ end
126
+ }
127
+ when :name
128
+ @entries.sort! {|x,y| x <=> y
129
+ if reverse
130
+ x <=> y
131
+ else
132
+ y <=> x
133
+ end
134
+ }
135
+ when :ext
136
+ @entries.sort! {|x,y|
137
+ if reverse
138
+ File.extname(cdir+x) <=> File.extname(cdir+y)
139
+ else
140
+ File.extname(cdir+y) <=> File.extname(cdir+x)
141
+ end
142
+ }
143
+ end
144
+ @sort_key = key
145
+ @entries.insert 0, first unless first.nil? # keep parent on top
146
+ populate @entries
147
+ end
148
+ GIGA_SIZE = 1073741824.0
149
+ MEGA_SIZE = 1048576.0
150
+ KILO_SIZE = 1024.0
151
+
152
+ # Return the file size with a readable style.
153
+ def readable_file_size(size, precision)
154
+ case
155
+ #when size == 1 : "1 B"
156
+ when size < KILO_SIZE : "%d B" % size
157
+ when size < MEGA_SIZE : "%.#{precision}f K" % (size / KILO_SIZE)
158
+ when size < GIGA_SIZE : "%.#{precision}f M" % (size / MEGA_SIZE)
159
+ else "%.#{precision}f G" % (size / GIGA_SIZE)
160
+ end
161
+ end
162
+ def date_format t
163
+ t.strftime "%Y/%m/%d"
164
+ end
165
+ def oldformat_string fn, stat
166
+ max_len = 30
167
+ f = fn.dup
168
+ if File.directory? f
169
+ #"%-*s\t(dir)" % [max_len,f]
170
+ #f = "/"+f # disallows search on keypress
171
+ f = f + "/ "
172
+ end
173
+ if f.size > max_len
174
+ f = f[0..max_len-1]
175
+ end
176
+ "%-*s\t%10s\t%s" % [max_len,f, readable_file_size(stat.size,1), date_format(stat.mtime)]
177
+ end
178
+ def cur_dir
179
+ @dir.path
180
+ end
181
+ alias :current_dir :cur_dir
182
+ def draw_screen dir=nil
183
+ cd dir unless dir.nil?
184
+ wdir = FileUtils.pwd
185
+ @prev_dirs << wdir
186
+ @dir = Dir.new(Dir.getwd)
187
+ @wdir = @dir.path
188
+ r = @row
189
+ c = @col
190
+ #cola = 1
191
+ #colb = Ncurses.COLS/2
192
+ ht = @ht
193
+ wid = @wid
194
+ #fl = Dir.glob(default_pattern)
195
+ #flist << format_string("..", nil)
196
+ fl = @dir.entries
197
+ fl.shift
198
+ filter(fl)
199
+ #flist = []
200
+ #fl.each {|f| stat = File.stat(f)
201
+ # flist << format_string(f, stat)
202
+ #}
203
+ @entries = fl
204
+ title = pwd()
205
+ @wdir = title
206
+ rfe = self
207
+
208
+ lista = Listbox.new @form do
209
+ name "lista"
210
+ row r
211
+ col c
212
+ width wid
213
+ height ht
214
+ #list flist
215
+ list fl
216
+ title wdir
217
+ #title_attrib 'reverse'
218
+ cell_renderer RfeRenderer.new "", {"color"=>@color, "bgcolor"=>@bgcolor, "parent" => rfe, "display_length"=> wid-2}
219
+ end
220
+ @list = lista
221
+ lista.bind(:ENTER) {|l| @rfe.current_list(self); l.title_attrib 'reverse'; }
222
+ lista.bind(:LEAVE) {|l| l.title_attrib 'normal'; }
223
+
224
+
225
+ #row_cmd = lambda {|list| file = list.list_data_model[list.current_index].split(/\t/)[0].strip; @rfe.status_row.text = File.stat("#{cur_dir()}/#{file}").inspect }
226
+ row_cmd = lambda {|lb, list| file = list.entries[lb.current_index]; @rfe.status_row.text = file; # File.stat("#{cur_dir()}/#{file}").inspect
227
+ }
228
+ lista.bind(:ENTER_ROW, self) {|lb,list| row_cmd.call(lb,list) }
229
+
230
+ end
231
+ def list_data
232
+ @list.list_data_model
233
+ end
234
+ def current_index
235
+ @list.current_index
236
+ end
237
+ def filename
238
+ #@entries[@list.current_index]
239
+ list_data()[current_index()]
240
+ end
241
+ def filepath
242
+ f = filename()
243
+ if f[0,1]=='/'
244
+ f
245
+ else
246
+ cur_dir() + "/" + filename()
247
+ end
248
+ end
249
+
250
+ end
251
+ class RFe
252
+ attr_reader :status_row
253
+ def initialize
254
+ @window = VER::Window.root_window
255
+ @form = Form.new @window
256
+ status_row = RubyCurses::Label.new @form, {'text' => "", :row => Ncurses.LINES-4, :col => 0, :display_length=>Ncurses.COLS-2}
257
+ @status_row = status_row
258
+ colb = Ncurses.COLS/2
259
+ ht = Ncurses.LINES - 7
260
+ wid = Ncurses.COLS/2 - 0
261
+ @lista = FileExplorer.new @form, self, row=2, col=1, ht, wid
262
+ @listb = FileExplorer.new @form, self, row=2, col=colb, ht, wid
263
+
264
+ init_vars
265
+ end
266
+ def init_vars
267
+ @bookmarks=[]
268
+ @config_name = File.expand_path("~/.rfe.yml")
269
+ if File.exist? @config_name
270
+ @config = YAML::load( File.open(@config_name));
271
+ if !@config.nil?
272
+ @bookmarks = @config["bookmarks"]||[]
273
+ @last_dirs = @config["last_dirs"]
274
+ end
275
+ end
276
+ @config ||={}
277
+ end
278
+ def save_config
279
+ @config["last_dirs"]=[@lista.current_dir(),@listb.current_dir()]
280
+ File.open(@config_name, "w") { | f | YAML.dump( @config, f )}
281
+ end
282
+ def move
283
+ fp = @current_list.filepath
284
+ fn = @current_list.filename
285
+ $log.debug " FP #{fp}"
286
+ other_list = [@lista, @listb].index(@current_list)==0 ? @listb : @lista
287
+ other_dir = other_list.cur_dir
288
+ $log.debug " OL #{other_list.cur_dir}"
289
+ str= "move #{fn} to #{other_list.cur_dir}"
290
+ $log.debug " MOVE #{fp}"
291
+ #confirm "#{str}"
292
+ mb = RubyCurses::MessageBox.new do
293
+ title "Move"
294
+ message "Move #{fn} to"
295
+ type :input
296
+ width 60
297
+ default_value other_dir
298
+ button_type :ok_cancel
299
+ default_button 0
300
+ end
301
+ #confirm "selected :#{mb.input_value}, #{mb.selected_index}"
302
+ if mb.selected_index == 0
303
+ # need to redraw directories
304
+ FileUtils.move(fp, mb.input_value)
305
+ @current_list.list.list_data_model.delete_at @current_list.list.current_index # ???
306
+ other_list.rescan
307
+ end
308
+ end
309
+ def copy
310
+ fp = @current_list.filepath
311
+ fn = @current_list.filename
312
+ $log.debug " FP #{fp}"
313
+ other_list = [@lista, @listb].index(@current_list)==0 ? @listb : @lista
314
+ other_dir = other_list.cur_dir
315
+ $log.debug " OL #{other_list.cur_dir}"
316
+ str= "copy #{fn} to #{other_list.cur_dir}"
317
+ $log.debug " copy #{fp}"
318
+ #confirm "#{str}"
319
+ mb = RubyCurses::MessageBox.new do
320
+ title "Copy"
321
+ message "Copy #{fn} to"
322
+ type :input
323
+ width 60
324
+ default_value other_dir
325
+ button_type :ok_cancel
326
+ default_button 0
327
+ end
328
+ #confirm "selected :#{mb.input_value}, #{mb.selected_index}"
329
+ if mb.selected_index == 0
330
+ # need to redraw directories
331
+ FileUtils.copy(fp, mb.input_value)
332
+ other_list.rescan
333
+ end
334
+ end
335
+ ## TODO : make this separate and callable with its own keylabels
336
+ def view content=nil
337
+ require 'rbcurse/rtextview'
338
+ wt = 0
339
+ wl = 0
340
+ wh = Ncurses.LINES-wt
341
+ ww = Ncurses.COLS-wl
342
+ if content.nil?
343
+ fp = @current_list.filepath
344
+ content = get_contents(fp)
345
+ else
346
+ fp=""
347
+ end
348
+ @layout = { :height => wh, :width => ww, :top => wt, :left => wl }
349
+ @v_window = VER::Window.new(@layout)
350
+ @v_form = RubyCurses::Form.new @v_window
351
+ @textview = TextView.new @v_form do
352
+ name "myView"
353
+ row 0
354
+ col 0
355
+ width ww
356
+ height wh-2
357
+ title fp
358
+ title_attrib 'bold'
359
+ print_footer true
360
+ footer_attrib 'bold'
361
+ end
362
+ #content = File.open(fp,"r").readlines
363
+ @textview.set_content content #, :WRAP_WORD
364
+ @v_form.repaint
365
+ @v_window.wrefresh
366
+ Ncurses::Panel.update_panels
367
+ begin
368
+ while((ch = @v_window.getchar()) != ?\C-q )
369
+ break if ch == KEY_F3
370
+ @v_form.handle_key ch
371
+ @v_form.repaint
372
+ ##@v_window.wrefresh
373
+ end
374
+ ensure
375
+ @v_window.destroy if !@v_window.nil?
376
+ end
377
+ end
378
+ def get_contents fp
379
+ return nil unless File.readable? fp
380
+ return Dir.new(fp).entries if File.directory? fp
381
+ case File.extname(fp)
382
+ when '.tgz','.gz'
383
+ cmd = "tar -ztvf #{fp}"
384
+ content = %x[#{cmd}]
385
+ else
386
+ content = File.open(fp,"r").readlines
387
+ end
388
+ end
389
+ def opt_file c
390
+ fp = @current_list.filepath
391
+ fn = @current_list.filename
392
+ other_list = [@lista, @listb].index(@current_list)==0 ? @listb : @lista
393
+ case c
394
+ when 'c'
395
+ # str= "copy #{fn} to #{other_list.cur_dir}"
396
+ copy
397
+ when 'm'
398
+ str= "move #{fn} to #{other_list.cur_dir}"
399
+ move
400
+ #if confirm("#{str}")==:YES
401
+ #$log.debug " MOVE #{str}"
402
+ #end
403
+ when 'd'
404
+ str= "delete #{fn} "
405
+ if confirm("#{str}")==:YES
406
+ $log.debug " delete #{fp}"
407
+ FileUtils.rm fp
408
+ ret=@current_list.list.list_data_model.delete_at @current_list.list.current_index # ???
409
+ $log.debug " DEL RET #{ret},#{@current_list.list.current_index}"
410
+ end
411
+ when 'u'
412
+ str= "move #{fn} to #{other_list.cur_dir}"
413
+ if confirm("#{str}")==:YES
414
+ $log.debug " MOVE #{str}"
415
+ end
416
+ when 'v'
417
+ str= "view #{fp}"
418
+ #if confirm("#{str}")==:YES
419
+ $log.debug " VIEW #{fp}"
420
+ view
421
+ #end
422
+ when 'r'
423
+ str= "ruby #{fn}"
424
+ if confirm("#{str}")=='y'
425
+ $log.debug " #{str} "
426
+ end
427
+ when 'e'
428
+ str= "edit #{fp}"
429
+ #if confirm("#{str}")==:YES
430
+ edit fp
431
+ when 'x'
432
+ str= "exec #{fp}"
433
+ exec_popup fp
434
+ end
435
+ end
436
+ def opt_dir c
437
+ fp = @current_list.filepath
438
+ fn = @current_list.filename
439
+ case c
440
+ when 'O'
441
+ # str= "copy #{fn} to #{other_list.cur_dir}"
442
+ if File.directory? @current_list.filepath
443
+ @current_list.change_dir fp
444
+ end
445
+ when 'o'
446
+ if File.directory? @current_list.filepath
447
+ @other_list.change_dir fp
448
+ end
449
+ @open_in_other = true # ???basically keep opening in other
450
+ when 'd'
451
+ str= "delete #{fn} "
452
+ if confirm("#{str}")==:YES
453
+ $log.debug " delete #{fp}"
454
+ FileUtils.rm fp
455
+ ret=@current_list.list.list_data_model.delete_at @current_list.list.current_index # ???
456
+ $log.debug " DEL RET #{ret},#{@current_list.list.current_index}"
457
+ end
458
+ when 'u'
459
+ str= "move #{fn} to #{other_list.cur_dir}"
460
+ if confirm("#{str}")==:YES
461
+ $log.debug " MOVE #{str}"
462
+ end
463
+ when 'b'
464
+ dd = @current_list.wdir
465
+ @bookmarks << dd unless @bookmarks.include? dd
466
+ when 'u'
467
+ dd = @current_list.wdir
468
+ @bookmarks.delete dd
469
+ when 'l'
470
+ @current_list.populate @bookmarks
471
+ when 's'
472
+ @config["bookmarks"] = @bookmarks
473
+ save_config
474
+ when 'e'
475
+ str= "edit #{fp}"
476
+ #if confirm("#{str}")==:YES
477
+ edit fp
478
+ when 'x'
479
+ str= "exec #{fp}"
480
+ exec_popup fp
481
+ end
482
+ end
483
+ def exec_popup fp
484
+ last_exec_def1 = @last_exec_def1 || ""
485
+ last_exec_def2 = @last_exec_def2 || false
486
+
487
+ sel, inp, hash = get_string_with_options("Enter a command to execute on #{fp}", 30, last_exec_def1, {"checkboxes" => ["view result"], "checkbox_defaults"=>[last_exec_def2]})
488
+ if sel == 0
489
+ @last_exec_def1 = inp
490
+ @last_exec_def2 = hash["view result"]
491
+ cmd = "#{inp} #{fp}"
492
+ filestr = %x[ #{cmd} 2>/dev/null ]
493
+ if hash["view result"]==true
494
+ view filestr
495
+ end
496
+ end
497
+ end
498
+ def edit fp=@current_list.filepath
499
+ $log.debug " edit #{fp}"
500
+ shell_out "/opt/local/bin/vim #{fp}"
501
+ end
502
+ def draw_screens
503
+ lasta = lastb = nil
504
+ if !@config["last_dirs"].nil?
505
+ lasta = @config["last_dirs"][0]
506
+ lastb = @config["last_dirs"][1]
507
+ end
508
+ @lista.draw_screen lasta
509
+ @listb.draw_screen lastb
510
+
511
+ @form.bind_key(?@){
512
+ @current_list.change_dir File.expand_path("~/")
513
+ }
514
+ @form.bind_key(?^){
515
+ @current_list.change_dir @current_list.prev_dirs[0] unless @current_list.prev_dirs.empty?
516
+ }
517
+ @form.bind_key(?\C-f){
518
+ @klp.mode :file
519
+ @klp.repaint
520
+ ## FIXME chr could fail !!
521
+ while((ch = @window.getchar()) != ?\C-c )
522
+ if "cmdsuvrex".index(ch.chr) == nil
523
+ Ncurses.beep
524
+ else
525
+ opt_file ch.chr
526
+ break
527
+ end
528
+ end
529
+ @klp.mode :normal
530
+ }
531
+ @form.bind_key(?\C-d){
532
+ @klp.mode :dir
533
+ @klp.repaint
534
+ keys = @klp.get_current_keys
535
+ ## FIXME chr could fail !!
536
+ while((ch = @window.getchar()) != ?\C-c )
537
+ if !keys.include?(ch.chr)
538
+ Ncurses.beep
539
+ else
540
+ opt_dir ch.chr
541
+ break
542
+ end
543
+ end
544
+ @klp.mode :normal
545
+ }
546
+ # backspace
547
+ @form.bind_key(127){
548
+ @current_list.goto_previous_dir
549
+ }
550
+ @form.bind_key(32){
551
+ begin
552
+ cmd="qlmanage -p #{@current_list.filepath} 2>/dev/null"
553
+ %x[#{cmd}]
554
+ rescue Interrupt
555
+ end
556
+ }
557
+ @form.bind_key(KEY_F3){
558
+ view()
559
+ }
560
+ @form.bind_key(KEY_F4){
561
+ edit()
562
+ }
563
+ @form.bind_key(KEY_F6){
564
+ selected_index, sort_key, reverse, case_sensitive = sort_popup
565
+ if selected_index == 0
566
+ @current_list.sort(sort_key, reverse)
567
+ end
568
+ }
569
+ @form.bind_key(KEY_F5){
570
+ filter()
571
+ }
572
+ @form.bind_key(KEY_F7){
573
+ grep_popup()
574
+ }
575
+ @form.bind_key(KEY_F8){
576
+ system_popup()
577
+ }
578
+ @form.bind_key(?\C-m){
579
+ dir = @current_list.filepath
580
+ if File.directory? @current_list.filepath
581
+ @current_list.change_dir dir
582
+ end
583
+ }
584
+ @klp = RubyCurses::KeyLabelPrinter.new @form, get_key_labels
585
+ @klp.set_key_labels get_key_labels(:file), :file
586
+ @klp.set_key_labels get_key_labels(:view), :view
587
+ @klp.set_key_labels get_key_labels(:dir), :dir
588
+ @form.repaint
589
+ @window.wrefresh
590
+ Ncurses::Panel.update_panels
591
+ begin
592
+ while((ch = @window.getchar()) != ?\C-q )
593
+ s = keycode_tos ch
594
+ status_row.text = "Pressed #{ch} , #{s}"
595
+ @form.handle_key(ch)
596
+
597
+ @form.repaint
598
+ @window.wrefresh
599
+ end
600
+ ensure
601
+ @window.destroy if !@window.nil?
602
+ save_config
603
+ end
604
+
605
+ end
606
+ # TODO
607
+ #
608
+ #
609
+ #
610
+
611
+ # current_list
612
+ ##
613
+ # getter and setter for current_list
614
+ def current_list(*val)
615
+ if val.empty?
616
+ @current_list
617
+ else
618
+ @current_list = val[0]
619
+ @other_list = [@lista, @listb].index(@current_list)==0 ? @listb : @lista
620
+ end
621
+ end
622
+ def get_key_labels categ=nil
623
+ if categ.nil?
624
+ key_labels = [
625
+ ['C-q', 'Exit'], ['C-v', 'View'],
626
+ ['C-f', 'File'], ['C-d', 'Dir'],
627
+ ['C-x','Select'], nil,
628
+ ['F3', 'View'], ['F4', 'Edit'],
629
+ ['F5', 'Filter'], ['F6', 'Sort'],
630
+ ['F7', 'Grep'], ['F8', 'System'],
631
+ ['M-0', 'Top'], ['M-9', 'End'],
632
+ ['C-p', 'PgUp'], ['C-n', 'PgDn']
633
+ ]
634
+ elsif categ == :file
635
+ key_labels = [
636
+ ['c', 'Copy'], ['m', 'Move'],
637
+ ['d', 'Delete'], ['v', 'View'],
638
+ ['s', 'Select'], ['u', 'Unselect'],
639
+ ['p', 'Page'], ['x', 'Exec Cmd'],
640
+ ['r', 'ruby'], ['e', "Edit"],
641
+ ['C-c', 'Cancel']
642
+ ]
643
+ elsif categ == :view
644
+ key_labels = [
645
+ ['c', 'Date'], ['m', 'Size'],
646
+ ['d', 'Delete'], ['v', 'View'],
647
+ ['C-c', 'Cancel']
648
+ ]
649
+ elsif categ == :dir
650
+ key_labels = [
651
+ ['o', 'open'], ['O', 'Open in right'],
652
+ ['d', 'Delete'], ['R', 'Del Recurse'],
653
+ ['t', 'tree'], ['p', 'Previous'],
654
+ ['b', 'Bookmark'], ['u', 'Unbookmark'],
655
+ ['l', 'List'], ['s', 'Save'],
656
+ ['C-c', 'Cancel']
657
+ ]
658
+ end
659
+ return key_labels
660
+ end
661
+ def get_key_labels_table
662
+ key_labels = [
663
+ ['M-n','NewRow'], ['M-d','DelRow'],
664
+ ['C-x','Select'], nil,
665
+ ['M-0', 'Top'], ['M-9', 'End'],
666
+ ['C-p', 'PgUp'], ['C-n', 'PgDn'],
667
+ ['M-Tab','Nxt Fld'], ['Tab','Nxt Col'],
668
+ ['+','Widen'], ['-','Narrow']
669
+ ]
670
+ return key_labels
671
+ end
672
+ def sort_popup
673
+ mform = RubyCurses::Form.new nil
674
+ field_list = []
675
+ r = 4
676
+ $radio = RubyCurses::Variable.new
677
+ rtextvalue = [:name, :ext, :size, :mtime, :atime]
678
+ ["Name", "Extension", "Size", "Modify Time", "Access Time" ].each_with_index do |rtext,ix|
679
+ field = RubyCurses::RadioButton.new mform do
680
+ variable $radio
681
+ text rtext
682
+ value rtextvalue[ix]
683
+ color 'black'
684
+ bgcolor 'white'
685
+ row r
686
+ col 5
687
+ end
688
+ field_list << field
689
+ r += 1
690
+ end
691
+ r = 4
692
+ ["Reverse", "case sensitive"].each do |cbtext|
693
+ field = RubyCurses::CheckBox.new mform do
694
+ text cbtext
695
+ name cbtext
696
+ color 'black'
697
+ bgcolor 'white'
698
+ row r
699
+ col 30
700
+ end
701
+ field_list << field
702
+ r += 1
703
+ end
704
+ mb = RubyCurses::MessageBox.new mform do
705
+ title "Sort Options"
706
+ button_type :ok_cancel
707
+ default_button 0
708
+ end
709
+ if mb.selected_index == 0
710
+ $log.debug " SORT POPUP #{$radio.value}"
711
+ #$log.debug " SORT POPUP #{mb.inspect}"
712
+ $log.debug " SORT POPUP #{mform.by_name["Reverse"].value}"
713
+ $log.debug " SORT POPUP #{mform.by_name["case sensitive"].value}"
714
+ end
715
+ return mb.selected_index, $radio.value, mform.by_name["Reverse"].value, mform.by_name["case sensitive"].value
716
+ end
717
+ def filter
718
+ f = get_string("Enter a filter pattern", 20, "*")
719
+ f = "*" if f.nil? or f == ""
720
+ @current_list.filter_pattern = f
721
+ @current_list.rescan
722
+ end
723
+ def grep_popup
724
+ last_regex = @last_regex || ""
725
+ last_pattern = @last_pattern || "*"
726
+ mform = RubyCurses::Form.new nil
727
+ r = 4
728
+ field = RubyCurses::Field.new mform do
729
+ name "regex"
730
+ row r
731
+ col 30
732
+ set_buffer last_regex
733
+ set_label Label.new @form, {'text' => 'Regex', 'col'=>5, :color=>'black',:bgcolor=>'white','mnemonic'=> 'R'}
734
+ end
735
+ r += 1
736
+ field = RubyCurses::Field.new mform do
737
+ name "filepattern"
738
+ row r
739
+ col 30
740
+ set_buffer last_pattern
741
+ set_label Label.new @form, {'text' => 'File Pattern','col'=>5, :color=>'black',:bgcolor=>'white','mnemonic'=> 'F'}
742
+ end
743
+ r += 1
744
+ ["Recurse", "case insensitive"].each do |cbtext|
745
+ field = RubyCurses::CheckBox.new mform do
746
+ text cbtext
747
+ name cbtext
748
+ color 'black'
749
+ bgcolor 'white'
750
+ row r
751
+ col 5
752
+ end
753
+ r += 1
754
+ end
755
+ mb = RubyCurses::MessageBox.new mform do
756
+ title "Grep Options"
757
+ button_type :ok_cancel
758
+ default_button 0
759
+ end
760
+ if mb.selected_index == 0
761
+ return if mform.by_name["regex"].getvalue()==""
762
+ @last_regex = mform.by_name["regex"].getvalue
763
+ inp = mform.by_name["regex"].getvalue
764
+ fp = mform.by_name["filepattern"].getvalue
765
+ @last_pattern = fp
766
+ flags=""
767
+ flags << " -i " if mform.by_name["case insensitive"].value==true
768
+ flags << " -R " if mform.by_name["Recurse"].value==true
769
+ cmd = "cd #{@current_list.cur_dir()};grep -l #{flags} #{inp} #{fp}"
770
+ filestr = %x[ #{cmd} ]
771
+ files = nil
772
+ files = filestr.split(/\n/) unless filestr.nil?
773
+ #view filestr
774
+ @current_list.title "grep #{inp}"
775
+ @current_list.populate files
776
+ end
777
+ return mb.selected_index, mform.by_name["regex"].getvalue, mform.by_name["filepattern"].getvalue, mform.by_name["Recurse"].value, mform.by_name["case insensitive"].value
778
+ end
779
+ def system_popup
780
+ deflt = @last_system || ""
781
+ options=["run in shell","view output","file explorer"]
782
+ #inp = get_string("Enter a system command", 30, deflt)
783
+ sel, inp, hash = get_string_with_options("Enter a system command", 40, deflt, {"radiobuttons" => options, "radio_default"=>@last_system_radio || options[0]})
784
+ if sel == 0
785
+ if !inp.nil?
786
+ @last_system = inp
787
+ @last_system_radio = hash["radio"]
788
+ case hash["radio"]
789
+ when options[0]
790
+ shell_out inp
791
+ when options[1]
792
+ filestr = %x[ #{inp} ]
793
+ view filestr
794
+ when options[2]
795
+ filestr = %x[ #{inp} ]
796
+ files = nil
797
+ files = filestr.split(/\n/) unless filestr.nil?
798
+ @current_list.title inp
799
+ @current_list.populate files
800
+ $log.debug " SYSTEM got #{files.size}, #{files.inspect}"
801
+ end
802
+ end
803
+ end
804
+ end
805
+ def popup
806
+ deflt = @last_regexp || ""
807
+ #sel, inp, hash = get_string_with_options("Enter a filter pattern", 20, "*", {"checkboxes" => ["case sensitive","reverse"], "checkbox_defaults"=>[true, false]})
808
+ sel, inp, hash = get_string_with_options("Enter a grep pattern", 20, deflt, {"checkboxes" => ["case insensitive","not-including"]})
809
+ if sel == 0
810
+ @last_regexp = inp
811
+ flags=""
812
+ flags << " -i " if hash["case insensitive"]==true
813
+ flags << " -v " if hash["not-including"]==true
814
+ cmd = "grep -l #{flags} #{inp} *"
815
+ filestr = %x[ #{cmd} ]
816
+ files = nil
817
+ files = filestr.split(/\n/) unless filestr.nil?
818
+ view filestr
819
+ end
820
+ $log.debug " POPUP: #{sel}: #{inp}, #{hash['case sensitive']}, #{hash['reverse']}"
821
+ end
822
+ def shell_out command
823
+ @window.hide
824
+ Ncurses.endwin
825
+ system command
826
+ Ncurses.refresh
827
+ #Ncurses.curs_set 0 # why ?
828
+ @window.show
829
+ end
830
+ end
831
+ if $0 == __FILE__
832
+ include RubyCurses
833
+ include RubyCurses::Utils
834
+
835
+ begin
836
+ # Initialize curses
837
+ VER::start_ncurses # this is initializing colors via ColorMap.setup
838
+ $log = Logger.new("view.log")
839
+ $log.level = Logger::DEBUG
840
+
841
+ catch(:close) do
842
+ t = RFe.new
843
+ t.draw_screens
844
+ end
845
+ rescue => ex
846
+ ensure
847
+ VER::stop_ncurses
848
+ p ex if ex
849
+ p(ex.backtrace.join("\n")) if ex
850
+ $log.debug( ex) if ex
851
+ $log.debug(ex.backtrace.join("\n")) if ex
852
+ end
853
+ end