rbhex-core 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (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