rbhex-core 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (108) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +20 -0
  3. data/CHANGELOG +2000 -0
  4. data/LICENSE +56 -0
  5. data/README.md +44 -0
  6. data/examples/abasiclist.rb +179 -0
  7. data/examples/alpmenu.rb +50 -0
  8. data/examples/app.sample +19 -0
  9. data/examples/atree.rb +100 -0
  10. data/examples/bline.rb +136 -0
  11. data/examples/common/file.rb +45 -0
  12. data/examples/data/README.markdown +9 -0
  13. data/examples/data/brew.txt +38 -0
  14. data/examples/data/color.2 +37 -0
  15. data/examples/data/gemlist.txt +60 -0
  16. data/examples/data/lotr.txt +12 -0
  17. data/examples/data/ports.txt +136 -0
  18. data/examples/data/table.txt +37 -0
  19. data/examples/data/tasks.csv +88 -0
  20. data/examples/data/tasks.txt +27 -0
  21. data/examples/data/todo.txt +10 -0
  22. data/examples/data/todo.txt.bak +10 -0
  23. data/examples/data/todocsv.csv +28 -0
  24. data/examples/data/unix1.txt +21 -0
  25. data/examples/data/unix2.txt +11 -0
  26. data/examples/dbdemo.rb +502 -0
  27. data/examples/dirtree.rb +94 -0
  28. data/examples/newtabbedwindow.rb +100 -0
  29. data/examples/newtesttabp.rb +92 -0
  30. data/examples/tabular.rb +146 -0
  31. data/examples/tasks.rb +178 -0
  32. data/examples/term2.rb +84 -0
  33. data/examples/testbuttons.rb +296 -0
  34. data/examples/testcombo.rb +102 -0
  35. data/examples/testfields.rb +195 -0
  36. data/examples/testkeypress.rb +72 -0
  37. data/examples/testlistbox.rb +170 -0
  38. data/examples/testmessagebox.rb +140 -0
  39. data/examples/testprogress.rb +116 -0
  40. data/examples/testree.rb +106 -0
  41. data/examples/testwsshortcuts.rb +66 -0
  42. data/examples/testwsshortcuts2.rb +128 -0
  43. data/lib/rbhex.rb +6 -0
  44. data/lib/rbhex/core/docs/index.txt +73 -0
  45. data/lib/rbhex/core/include/action.rb +80 -0
  46. data/lib/rbhex/core/include/actionmanager.rb +49 -0
  47. data/lib/rbhex/core/include/appmethods.rb +214 -0
  48. data/lib/rbhex/core/include/bordertitle.rb +48 -0
  49. data/lib/rbhex/core/include/chunk.rb +203 -0
  50. data/lib/rbhex/core/include/io.rb +553 -0
  51. data/lib/rbhex/core/include/listbindings.rb +74 -0
  52. data/lib/rbhex/core/include/listcellrenderer.rb +140 -0
  53. data/lib/rbhex/core/include/listeditable.rb +317 -0
  54. data/lib/rbhex/core/include/listscrollable.rb +663 -0
  55. data/lib/rbhex/core/include/listselectable.rb +271 -0
  56. data/lib/rbhex/core/include/multibuffer.rb +83 -0
  57. data/lib/rbhex/core/include/orderedhash.rb +77 -0
  58. data/lib/rbhex/core/include/ractionevent.rb +73 -0
  59. data/lib/rbhex/core/include/rchangeevent.rb +27 -0
  60. data/lib/rbhex/core/include/rhistory.rb +95 -0
  61. data/lib/rbhex/core/include/rinputdataevent.rb +47 -0
  62. data/lib/rbhex/core/include/vieditable.rb +172 -0
  63. data/lib/rbhex/core/include/widgetmenu.rb +66 -0
  64. data/lib/rbhex/core/system/colormap.rb +165 -0
  65. data/lib/rbhex/core/system/keyboard.rb +150 -0
  66. data/lib/rbhex/core/system/keydefs.rb +30 -0
  67. data/lib/rbhex/core/system/ncurses.rb +236 -0
  68. data/lib/rbhex/core/system/panel.rb +162 -0
  69. data/lib/rbhex/core/system/window.rb +913 -0
  70. data/lib/rbhex/core/util/ansiparser.rb +119 -0
  71. data/lib/rbhex/core/util/app.rb +1228 -0
  72. data/lib/rbhex/core/util/basestack.rb +410 -0
  73. data/lib/rbhex/core/util/bottomline.rb +1859 -0
  74. data/lib/rbhex/core/util/colorparser.rb +77 -0
  75. data/lib/rbhex/core/util/focusmanager.rb +31 -0
  76. data/lib/rbhex/core/util/padreader.rb +192 -0
  77. data/lib/rbhex/core/util/rcommandwindow.rb +604 -0
  78. data/lib/rbhex/core/util/rdialogs.rb +574 -0
  79. data/lib/rbhex/core/util/viewer.rb +149 -0
  80. data/lib/rbhex/core/util/widgetshortcuts.rb +506 -0
  81. data/lib/rbhex/core/version.rb +5 -0
  82. data/lib/rbhex/core/widgets/applicationheader.rb +103 -0
  83. data/lib/rbhex/core/widgets/box.rb +58 -0
  84. data/lib/rbhex/core/widgets/divider.rb +310 -0
  85. data/lib/rbhex/core/widgets/keylabelprinter.rb +194 -0
  86. data/lib/rbhex/core/widgets/rcombo.rb +253 -0
  87. data/lib/rbhex/core/widgets/rcontainer.rb +415 -0
  88. data/lib/rbhex/core/widgets/rlink.rb +30 -0
  89. data/lib/rbhex/core/widgets/rlist.rb +696 -0
  90. data/lib/rbhex/core/widgets/rmenu.rb +958 -0
  91. data/lib/rbhex/core/widgets/rmenulink.rb +22 -0
  92. data/lib/rbhex/core/widgets/rmessagebox.rb +387 -0
  93. data/lib/rbhex/core/widgets/rprogress.rb +118 -0
  94. data/lib/rbhex/core/widgets/rtabbedpane.rb +634 -0
  95. data/lib/rbhex/core/widgets/rtabbedwindow.rb +70 -0
  96. data/lib/rbhex/core/widgets/rtextarea.rb +960 -0
  97. data/lib/rbhex/core/widgets/rtextview.rb +739 -0
  98. data/lib/rbhex/core/widgets/rtree.rb +768 -0
  99. data/lib/rbhex/core/widgets/rwidget.rb +3277 -0
  100. data/lib/rbhex/core/widgets/scrollbar.rb +143 -0
  101. data/lib/rbhex/core/widgets/statusline.rb +113 -0
  102. data/lib/rbhex/core/widgets/tabular.rb +264 -0
  103. data/lib/rbhex/core/widgets/tabularwidget.rb +1142 -0
  104. data/lib/rbhex/core/widgets/textpad.rb +995 -0
  105. data/lib/rbhex/core/widgets/tree/treecellrenderer.rb +150 -0
  106. data/lib/rbhex/core/widgets/tree/treemodel.rb +428 -0
  107. data/rbhex-core.gemspec +32 -0
  108. metadata +172 -0
@@ -0,0 +1,37 @@
1
+ 69|C-u not available for textpad and view. how to|P2|open
2
+ 85|combo symbol when label, see newmessagebox|P2|open
3
+ 86|combo let caller suggest width and use if longer than longest item|P2|open
4
+ 88|keep working on wsshortcuts as in testws..2.rb|P2|open
5
+ 89|messagebox, see about background for zterm-256 as in header|P2|open
6
+ 97|binding to KEY_ENTER doesn't work, have to bid to 13|P2|open
7
+ 98|if list not binding ENTER then dont consume it|P2|open
8
+ 22|widget hide (visible false) does not hide|P3|open
9
+ 65|clean up window.rb prv_printstring etc|P3|open
10
+ 74|list and others should just calculate longest in list|P3|open
11
+ 79|cleanup button getpaint etc|P3|open
12
+ 80|use @focusable in form to simplify|P3|open
13
+ 87|praps global setting lists etc use SPC for scroll or selection|P3|open
14
+ 92|messagebox: if text longer than display then can we split|P3|open
15
+ 95|window.refresh required after alert of messagebox closes|P3|open
16
+ 99|button option to set mnemo for keys without alt|P3|open
17
+ 10|combo keys|P4|open
18
+ 17|selected_item of list broken|P4|open
19
+ 20|cannot bind_key using Alt key and another. |P4|open
20
+ 27|#fix testvimsplit not sizing STACK correctly|P4|open
21
+ 32| #tree many empty methods in #treemodel|P4|open
22
+ 37|simplify #vimsplit calculation|P4|open
23
+ 52|%label set_label may have to calculate at repaint esp in app|P4|open
24
+ 55|Have a module Expandable for those that are multiline|P4|open
25
+ 56|DRY up titles and borders|P4|open
26
+ 60|fields width, display_len is for input area, not label plus input|P4|open
27
+ 61|test2.rb color change not affecting text objects|P4|open
28
+ 70|confusion between renderer and color_parser|P4|open
29
+ 75|textpad to allow append << at some stage|P4|open
30
+ 93|messagebox conform and choice whith single key getch|P4|open
31
+ 8|container keep repainting all|P5|open
32
+ 26|App to have a layout abject |P5|open
33
+ 39|tabularwidget truncate needed left_margin|P5|open
34
+ 42|append_to_kill, yank not working in %listbox|P5|open
35
+ 49|resultsetview needs way to specify key fields|P5|open
36
+ 50|sort on tabularwidget with resultset error sometimes|P5|open
37
+ 96|configure confirm quit etc through a file|P5|open
@@ -0,0 +1,88 @@
1
+ 1|clo|bug|X3|messagebox label print overlaps left border
2
+ 2|clo|enh|P4|Field: methods not chainable
3
+ 3|clo|bug|P3|button crash if mnemo not in text
4
+ 4|clo|enh|P3|link mnemo should not have Alt
5
+ 8|ope|bug|P5|container keep repainting all
6
+ 9|clo|enh|P3|menu bar keys
7
+ 10|ope|enh|P4|combo keys
8
+ 11|clo|bug|X3|hand written DSL defs dont fire prop handler
9
+ 12|clo|bug|X4|textview on_enter
10
+ 13|clo|enh|P3|traversal of listboxes
11
+ 14|clo|enh|P3|check keys Alt-Sh-O, Alt-[. Add some missing
12
+ 15|clo|bug|P3|2 keys simulaneously with Alt-O or Alt-[
13
+ 16|clo|enh|P3|put key combins in arrays and match
14
+ 17|ope|bug|P4|selected_item of list broken
15
+ 18|clo|enh|P3|valid_range for Field
16
+ 19|clo|bug|X2|tree can print beyond right margin
17
+ 20|ope|bug|P4|cannot bind_key using Alt key and another.
18
+ 21|sta|enh|P2|make code from App common so reusable in other examples
19
+ 22|ope|bug|P3|widget hide (visible false) does not hide
20
+ 23|clo|bug|P3|listbox color changes not reflecting in cell_renderer
21
+ 24|clo|bug|P3|Table: delete row should reflect focussed_index.
22
+ 25|clo|enh|X3|#cleanup add_cols rows_panned #urgent
23
+ 26|ope|fea|P5|App to have a layout abject
24
+ 27|ope|bug|P4|#fix testvimsplit not sizing STACK correctly
25
+ 28|clo|enh|P1|FieldValidationException should rollback change,
26
+ 29|clo|enh|X1|return self from dsl_prop and dsl_accessor,
27
+ 30|can|bug|P3|on_leave has validations that should be separated,
28
+ 31|clo|enh|X1|#listbox data more accessible from LB class,
29
+ 32|ope|enh|P4| #tree many empty methods in #treemodel
30
+ 33|clo|enh|X3|display_menu shd furhter glob on tab
31
+ 34|clo|enh|X3|display_menu large list need scrolling
32
+ 35|clo|bug|X3|alert message getting truncated after 2 lines
33
+ 36|clo|fea|X3|use j k h l for navigation if unused by a button of widget
34
+ 37|ope|enh|P4|simplify #vimsplit calculation
35
+ 38|clo|bug|X3|#tabbedpane when fire, state of old tab discrep
36
+ 39|ope|bug|P5|tabularwidget truncate needed left_margin
37
+ 40|clo|bug|X3|%textarea C-e goes to last char, not one after that
38
+ 41|clo|bug|X3|M-2 did not work in textarea
39
+ 42|ope|bug|P5|append_to_kill, yank not working in %listbox
40
+ 43|clo|bug|X1|rt arrow and backspace issue ask(), dbdemo save #urgent
41
+ 44|clo|bug|P1|need to hide window after ask(), dbdemo save
42
+ 45|clo|bug|X3|directory list, after pressing Enter on ../ focus on header
43
+ 46|clo|enh|X3|textview repaints all even when no scrolling
44
+ 47|ope|enh|P4|vieditable and io.rb need to create statuswindow and take input
45
+ 48|clo|bug|X3|say not working after ask hides window
46
+ 49|ope|enh|P5|resultsetview needs way to specify key fields
47
+ 50|ope|bug|P5|sort on tabularwidget with resultset error sometimes
48
+ 51|clo|bug|X2|TabbedPane's TabbedButtons rely on window being 0,0
49
+ 52|ope|bug|P4|%label set_label may have to calculate at repaint esp in app
50
+ 53|clo|bug|X3|%App. if shortcut used outside stack or flow, dont attach form or set
51
+ 54|clo|bug|X3|inside newtabbedpane button mnemonic and underline not happening #fix
52
+ 55|ope|enh|P4|Have a module Expandable for those that are multiline
53
+ 56|ope|enh|P4|DRY up titles and borders
54
+ 57|clo|enh|X2|dont put default for color and bg in init of Wid or field
55
+ 58|clo|enh|X2|Fields display_length should be width or made alias
56
+ 60|ope|enh|P4|fields width, display_len is for input area, not label plus input
57
+ 61|ope|bug|P4|test2.rb color change not affecting text objects
58
+ 62|clo|bug|X2|when using chunks, movement crashes C-e etc
59
+ 63|clo|bug|X2|chunks in textview, when scrolling earlier lines shown
60
+ 64|clo|enh|X2|abstract chunk and parse into Format class
61
+ 65|ope|enh|P3|clean up window.rb prv_printstring etc
62
+ 66|clo|bug|X2|colorparser needs to carryover, and :reset
63
+ 67|clo|enh|X3|several places doing attrib conversion in window, use get_attrib
64
+ 68|clo|bug|X4|move chunk parsing from window.rb to chunk as in textview
65
+ 69|ope|bug|P2|C-u not available for textpad and view. how to
66
+ 70|ope|enh|P4|confusion between renderer and color_parser
67
+ 71|clo|enh|X1|redo combo with basiclist or new popup
68
+ 72|clo|enh|X2|redo label simplify, one line only
69
+ 73|clo|bug|X2|rbasiclist needs to reduce selected symbol
70
+ 74|ope|enh|P3|list and others should just calculate longest in list
71
+ 75|ope|enh|P4|textpad to allow append << at some stage
72
+ 76|clo|enh|X3|appmethods.rb may need to go into lib/common or somewhere else
73
+ 77|clo|enh|X2|switch messagebox old and new and change rdialog
74
+ 78|clo|enh|X1|switch tabbedpane classes and update examples
75
+ 79|ope|enh|P3|cleanup button getpaint etc
76
+ 80|ope|enh|P3|use @focusable in form to simplify
77
+ 81|clo|bug|X2|field label mnemonic not being set
78
+ 82|ope|bug|P2|new messagebox need default_button option
79
+ 83|clo|enh|X2|check statusline usage, should use formatted only
80
+ 84|clo|bug|X2|dbdemo M-z not doing anything
81
+ 85|ope|bug|P2|combo symbol when label, see newmessagebox
82
+ 86|ope|bug|P2|combo let caller suggest width and use if longer than longest item
83
+ 87|ope|enh|P3|praps global setting lists etc use SPC for scroll or selection
84
+ 88|ope|enh|P2|keep working on wsshortcuts as in testws..2.rb
85
+ 89|ope|bug|P2|messagebox, see about background for zterm-256 as in header
86
+ 90|clo|bug|X2|messagebox: message sets width, even if user has specified
87
+ 91|clo|enh|X2|messagebox: default row col cannot be 0,0
88
+ 92|ope|enh|P3|messagebox: if text longer than display then can we split
@@ -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
@@ -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,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,502 @@
1
+ require 'rbhex/core/util/app'
2
+ require 'sqlite3'
3
+ #require 'rbhex/experimental/resultsettextview.rb'
4
+ #require 'rbhex/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) if 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
+ #
63
+ # changed order of name and fields, thanks hramrach
64
+ def view_data name, fields="*"
65
+ stmt = "select #{fields} from #{name}"
66
+ stmt << $where_string if $where_string
67
+ stmt << $order_string if $order_string
68
+ view_sql stmt
69
+ @form.by_name['tarea'] << stmt if @form # nil when called from menu
70
+ end
71
+ def view_sql stmt
72
+ begin
73
+ content = get_data stmt
74
+ if content.nil?
75
+ else
76
+ require 'rbhex/core/widgets/tabular'
77
+ t = Tabular.new do |t|
78
+ t.headings = $columns
79
+ t.data=content
80
+ end
81
+ view t.render
82
+ end
83
+ rescue => err
84
+ $log.error err.to_s
85
+ $log.error(err.backtrace.join("\n"))
86
+ textdialog [err.to_s, *err.backtrace], :title => "Exception"
87
+ end
88
+ end
89
+
90
+ App.new do
91
+ #header = app_header "rbhex #{Rbhex::Core::VERSION}", :text_center => "Database Demo", :text_right =>"enabled"
92
+ form = @form
93
+ mylabel = "a field"
94
+ $catch_alt_digits = true # use M-1..9 in textarea
95
+ $current_table = nil
96
+ $current_db = nil # "testd.db"
97
+ connect $current_db if $current_db
98
+ def which_field
99
+ alert "curent field is #{form.get_current_field} "
100
+ end
101
+
102
+ def get_commands
103
+ %w{ which_field }
104
+ end
105
+ def help_text
106
+ <<-eos
107
+ DBDEMO HELP
108
+
109
+ This is some help text for dbdemo.
110
+ We are testing out this feature.
111
+
112
+ Alt-d - Select a database
113
+ <Enter> on a table, view data (q to close window)
114
+ <Space> on a table, display columns in lower list
115
+
116
+ COLUMN LIST KEYS
117
+ <Space> on a column for multiple select
118
+ <Ctrl-Space> on a column for range select/deselect from previous selection
119
+ <Enter> on column table to view data for selected columns
120
+ u unselect all
121
+ a select all
122
+ * invert selection
123
+ F4 View data for selected table (or columns if selected)
124
+
125
+ q or C-q Close the data window that comes on Enter or F4
126
+
127
+ Alt-x - Command mode (<tab> to see commands and select)
128
+ : - Command mode
129
+ Alt-z - Commands in TextArea
130
+
131
+ Sql Entry Area
132
+ C-x e Edit in $EDITOR or vi
133
+ M-? To see other key-bindings
134
+ F4 Execute SQL (there should be only one sql).
135
+
136
+
137
+ Result Set (this is not present in this demo any longer - moved
138
+ to rbhex-extras)
139
+ , Prev row (mnemonic <)
140
+ . Next row (mnemonic >)
141
+ < First row
142
+ > Last row
143
+
144
+ F10 - Quit application
145
+
146
+
147
+
148
+ -----------------------------------------------------------------------
149
+ Hope you enjoyed this help.
150
+ eos
151
+ end
152
+ def ask_databases
153
+ names = Dir.glob("*.{sqlite,db}")
154
+ if names
155
+ ix = popuplist( names )
156
+ if ix
157
+ value = names[ix]
158
+ connect(value);
159
+ @form.by_name["tlist"].list(get_table_names)
160
+ end
161
+
162
+ else
163
+ alert "Can't find a .db or .sqlite file"
164
+ end
165
+ end
166
+ @form.help_manager.help_text = help_text()
167
+ # TODO accelerators and
168
+ # getting a handle for later use
169
+ mb = menubar do
170
+ keep_visible true
171
+ #@toggle_key=KEY_F2
172
+ menu "File" do
173
+ item "Open", "O" do
174
+ accelerator "Ctrl-O"
175
+ command do
176
+ alert "HA!! you wanted to open a file?"
177
+ end
178
+ end
179
+ menu "Database" do
180
+ item_list do
181
+ Dir.glob("**/*.{sqlite,db}")
182
+ end
183
+ command do |menuitem, text|
184
+ connect text
185
+ form.by_name["tlist"].list(get_table_names)
186
+ end
187
+ end
188
+ menu "Tables" do
189
+ item_list do
190
+ if $current_db
191
+ get_table_names
192
+ end
193
+ end
194
+ command do |menuitem, text|
195
+ $current_table = text
196
+ #alert(get_column_names(text).join(", "))
197
+ create_popup(get_column_names(text), :multiple) { |value| view_data( text, value.join(",") ) }
198
+ end
199
+ end
200
+ item "New", "N"
201
+ separator
202
+ item "Exit", "x" do
203
+ command do
204
+ throw(:close)
205
+ end
206
+ end
207
+ item "Cancel Menu" do
208
+ accelerator "Ctrl-g"
209
+ end
210
+
211
+ end # menu
212
+ menu "Window" do
213
+ item "Tile", "T"
214
+ menu "Find" do
215
+ item "More", "M"
216
+ $x = item "Less", "L" do
217
+ #accelerator "Ctrl-X"
218
+ command do
219
+ alert "You clickses on Less"
220
+ end
221
+ end
222
+ menu "Size" do
223
+ item "Zoom", "Z"
224
+ item "Maximize", "X"
225
+ item "Minimize", "N"
226
+ end
227
+ end
228
+ end
229
+ menu "Others" do
230
+ require 'rbhex/core/include/appmethods.rb'
231
+ item "Shell Output" do
232
+ command { shell_output }
233
+ end
234
+ item "Suspend" do
235
+ command { suspend }
236
+ end
237
+ end
238
+ end # menubar
239
+ mb.toggle_key = FFI::NCurses::KEY_F2
240
+ mb.color = :white
241
+ mb.bgcolor = :blue
242
+ @form.set_menu_bar mb
243
+ tv = nil
244
+ flow :margin_top => 1 do
245
+ col1w = 20
246
+ stack :width_pc => 20 do
247
+ text = "No tables"
248
+ if !$current_db
249
+ text = "Select DB first. Press Alt-D"
250
+ end
251
+ tlist = basiclist :name => "tlist", :list => [text], :title => "Tables", :height => 10,
252
+ :selected_color => 'cyan', :selected_bgcolor => 'black' , :selected_attr => Ncurses::A_REVERSE,
253
+ :help_text => "Enter to View complete table, Space to select table and view columns",
254
+ :should_show_focus => true,
255
+ :selection_mode => :single
256
+ tlist.bind(:PRESS) do |eve|
257
+ if $current_db
258
+ # get data of table
259
+ view_data eve.text
260
+ #tv.sqlite $current_db, eve.text, "select * from #{eve.text} " # TODO in core
261
+ else
262
+ ask_databases
263
+ end
264
+ end
265
+ #tlist.bind(:ENTER_ROW) do |eve|
266
+ # too much confusion between selected and focussed row
267
+ #$current_table = eve.text if $db
268
+ #end
269
+ clist = basiclist :name => "clist", :list => ["No columns"], :title => "Columns", :height => 14,
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"
273
+ tlist.bind(:LIST_SELECTION_EVENT) do |eve|
274
+ $selected_table = eve.source[eve.firstrow]
275
+ $current_table = $selected_table
276
+ clist.data = get_column_names $selected_table
277
+ end
278
+ clist.bind(:PRESS) do |eve|
279
+ # get data of table
280
+ if $selected_table
281
+ cols = "*"
282
+ c = clist.get_selected_values
283
+ unless c.empty?
284
+ cols = c.join(",")
285
+ end
286
+ view_data $selected_table, cols
287
+ else
288
+ alert "Select a table first."
289
+ end
290
+ end
291
+ clist.bind_key('w', 'add to where condition') {
292
+ c = clist.current_value
293
+ $where_columns ||= []
294
+ hist = ["#{c} = "]
295
+ w = rb_gets("where "){ |q| q.default = "#{c} = "; q.history = hist }
296
+ $where_columns << w if w
297
+ message "where: #{$where_columns.last}. Press F4 when done"
298
+ $log.debug "XXX: WHERE: #{$where_columns} "
299
+ }
300
+ clist.bind_key('o', 'add to order by') {
301
+ c = clist.current_value
302
+ $order_columns ||= []
303
+ $order_columns << c if c
304
+ message "order (asc): #{$order_columns.last}. Press F4 when done"
305
+ $log.debug "XXX: ORDER: #{$order_columns} "
306
+ }
307
+ clist.bind_key('O', 'add to ordery by desc') {
308
+ c = clist.current_value
309
+ $order_columns ||= []
310
+ $order_columns << " #{c} desc " if c
311
+ message "order: #{$order_columns.last}"
312
+ $log.debug "XXX: ORDER: #{$order_columns}. Press F4 when done"
313
+ }
314
+ @statusline = status_line
315
+ #wg = get_color($datacolor, 'white','green')
316
+ #wb = get_color($datacolor, 'white','blue')
317
+ @statusline.command {
318
+ # trying this out. If you want a persistent message that remains till the next on
319
+ # then send it in as $status_message
320
+ text = $status_message.value || ""
321
+ if !$current_db
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] ]
325
+ elsif !$current_table
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] ]
328
+ else
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] ]
332
+ end
333
+ }
334
+ @adock = nil
335
+ keyarray = [
336
+ ["F1" , "Help"], ["F10" , "Exit"],
337
+ ["F2", "Menu"], ["F4", "View"],
338
+ ["M-d", "Datebase"], ["M-t", "Table"],
339
+ ["M-x", "Command"], nil
340
+ ]
341
+ tlist_keyarray = keyarray + [ ["Sp", "Select"], nil, ["Enter","View"] ]
342
+
343
+ clist_keyarray = keyarray + [ ["Sp", "Select"], ["C-sp", "Range Sel"],
344
+ ["Enter","View"], ['w', 'where'],
345
+ ["o","order by"], ['O', 'order desc']
346
+ ]
347
+ tarea_keyarray = keyarray + [ ["M-z", "Commands"], nil ]
348
+ #tarea_sub_keyarray = [ ["r", "Run"], ["c", "clear"], ["w","Save"], ["a", "Append next"],
349
+ #["y", "Yank"], ["Y", "yank pop"] ]
350
+ tarea_sub_keyarray = [ ["r", "Run"], ["c", "clear"], ["e", "Edit externally"], ["w","Kill Ring Save (M-w)"], ["a", "Append Next"],
351
+ ["y", "Yank (C-y)"], ["Y", "yank pop (M-y)"],
352
+ ["u", "Undo (C-_)"], ["R", "Redo (C-r)"],
353
+ ]
354
+
355
+ gw = get_color($reversecolor, 'green', 'black')
356
+ @adock = dock keyarray, { :row => Ncurses.LINES-2, :footer_color_pair => $datacolor,
357
+ :footer_mnemonic_color_pair => gw }
358
+ @adock.set_key_labels tlist_keyarray, :tables
359
+ @adock.set_key_labels clist_keyarray, :columns
360
+ @adock.set_key_labels tarea_sub_keyarray, :tarea_sub
361
+ @adock.set_key_labels tarea_keyarray, :tarea
362
+ tlist.bind(:ENTER) { @adock.mode :tables }
363
+ clist.bind(:ENTER) { @adock.mode :columns }
364
+
365
+ reduce = lambda { |obj|
366
+ obj.height -= 1 if obj.height > 3
367
+ }
368
+ increase = lambda { |obj|
369
+ obj.height += 1 if obj.height + obj.row < Ncurses.LINES-2
370
+ }
371
+ _lower = lambda { |obj|
372
+ obj.row += 1 if obj.height + obj.row < Ncurses.LINES-2
373
+ }
374
+ _raise = lambda { |obj|
375
+ obj.row -= 1 if obj.row > 2
376
+ }
377
+ [clist, tlist].each do |o|
378
+ o.bind_key([?\C-x, ?-]){ |o| reduce.call(o) }
379
+ o.bind_key([?\C-x, ?+]){ |o| increase.call(o) }
380
+ o.bind_key([?\C-x, ?v]){ |o| _lower.call(o) }
381
+ o.bind_key([?\C-x, ?6]){ |o| _raise.call(o) }
382
+ end
383
+
384
+
385
+ @form.bind_key([?q,?q], 'quit') { throw :close }
386
+ @form.bind_key(?\M-t, 'select table') do
387
+ if $current_db.nil?
388
+ alert "Please select database first"
389
+ else
390
+ create_popup( get_table_names,:single) {|value| $selected_table = $current_table = value}
391
+ end
392
+ end
393
+ @form.bind_key(?\M-d, 'select database') do
394
+ ask_databases
395
+ end
396
+ @form.bind_key(FFI::NCurses::KEY_F4, 'view data') do
397
+ $where_string = nil
398
+ $order_string = nil
399
+ if $where_columns
400
+ $where_string = " where " + $where_columns.join(" and ")
401
+ end
402
+ if $order_columns
403
+ $order_string = " order by " + $order_columns.join(" , ")
404
+ end
405
+ # mismatch between current and selected table
406
+ if $current_table
407
+ cols = "*"
408
+ c = clist.get_selected_values
409
+ unless c.empty?
410
+ cols = c.join(",")
411
+ end
412
+ view_data $current_table, cols
413
+ else
414
+ alert "Select a table first."
415
+ end
416
+ end
417
+ end # stack
418
+ stack :width_pc => 80 do
419
+ tarea = textarea :name => 'tarea', :height => 5, :title => 'Sql Statement'
420
+ #undom = SimpleUndo.new tarea
421
+ tarea.bind_key(Ncurses::KEY_F4, 'view data') do
422
+ text = tarea.get_text
423
+ if text == ""
424
+ alert "Please enter a query and then hit F4. Or press F4 over column list"
425
+ else
426
+ view_sql tarea.get_text
427
+ end
428
+ end
429
+ tarea.bind(:ENTER) { @adock.mode :tarea }
430
+ tarea.bind_key(?\M-z, 'textarea submenu'){
431
+
432
+ hash = { 'c' => lambda{ tarea.remove_all },
433
+ 'e' => lambda{ tarea.edit_external },
434
+ 'w' => lambda{ tarea.kill_ring_save },
435
+ 'a' => lambda{ tarea.append_next_kill },
436
+ 'y' => lambda{ tarea.yank },
437
+ 'Y' => lambda{ tarea.yank_pop },
438
+ 'r' => lambda{ view_sql tarea.get_text },
439
+ 'u' => lambda{ tarea.undo },
440
+ 'R' => lambda{ tarea.redo },
441
+ }
442
+
443
+
444
+ @adock.mode :tarea_sub
445
+ @adock.repaint
446
+ keys = @adock.get_current_keys
447
+ while((ch = @window.getchar()) != ?\C-c.getbyte(0) )
448
+ if ch < 33 || ch > 126
449
+ Ncurses.beep
450
+ elsif !keys.include?(ch.chr)
451
+ Ncurses.beep
452
+ else
453
+ hash.fetch(ch.chr).call
454
+ #opt_file ch.chr
455
+ break
456
+ end
457
+ end
458
+ @adock.mode :normal
459
+ } # M-z
460
+ flow do
461
+ #button_row = 17
462
+ button "Save" do
463
+ @cmd_history ||= []
464
+ filename = rb_gets("File to append contents to: ") { |q| q.default = @oldfilename; q.history = @cmd_history }
465
+
466
+ if filename
467
+ str = tarea.get_text
468
+ File.open(filename, 'a') {|f| f.write(str) }
469
+ @oldfilename = filename
470
+ @cmd_history << filename unless @cmd_history.include? filename
471
+
472
+ message "Appended data to #{filename}"
473
+ else
474
+ message "Aborted operation"
475
+ end
476
+ #hide_bottomline
477
+ end
478
+ button "Read" do
479
+ filter = "*"
480
+ #str = choose filter, :title => "Files", :prompt => "Choose a file: "
481
+ cproc = Proc.new { |str| Dir.glob(str + "*") }
482
+ str = rb_gets "Choose a file: ", :title => "Files", :tab_completion => cproc,
483
+ :help_text => "Press <tab> to complete filenames. C-a, C-e, C-k. Alt-?"
484
+ if str && File.exists?(str)
485
+ begin
486
+ tarea.set_content(str)
487
+ message "Read content from #{str} "
488
+ rescue => err
489
+ print_error_message "No file named: #{str}: #{err.to_s} "
490
+ end
491
+ end
492
+ end
493
+ #ok_button = button( [button_row,30], "OK", {:mnemonic => 'O'}) do
494
+ #end
495
+ end
496
+ blank
497
+ #tv = RubyCurses::ResultsetTextView.new @form, :row => 1, :col => 1, :width => 50, :height => 16
498
+ #tv = resultsettextview :name => 'resultset', :height => 18 , :title => 'DB Browser', :print_footer => true
499
+
500
+ end
501
+ end
502
+ end # app