canis 0.0.4

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 (134) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +45 -0
  3. data/CHANGES +52 -0
  4. data/Gemfile +4 -0
  5. data/LICENSE.txt +22 -0
  6. data/README.md +24 -0
  7. data/Rakefile +2 -0
  8. data/canis.gemspec +25 -0
  9. data/examples/alpmenu.rb +46 -0
  10. data/examples/app.sample +19 -0
  11. data/examples/appemail.rb +191 -0
  12. data/examples/atree.rb +105 -0
  13. data/examples/bline.rb +181 -0
  14. data/examples/common/devel.rb +319 -0
  15. data/examples/common/file.rb +93 -0
  16. data/examples/data/README.markdown +9 -0
  17. data/examples/data/brew.txt +38 -0
  18. data/examples/data/color.2 +37 -0
  19. data/examples/data/gemlist.txt +59 -0
  20. data/examples/data/lotr.txt +12 -0
  21. data/examples/data/ports.txt +136 -0
  22. data/examples/data/table.txt +37 -0
  23. data/examples/data/tasks.csv +88 -0
  24. data/examples/data/tasks.txt +27 -0
  25. data/examples/data/todo.txt +16 -0
  26. data/examples/data/todocsv.csv +28 -0
  27. data/examples/data/unix1.txt +21 -0
  28. data/examples/data/unix2.txt +11 -0
  29. data/examples/dbdemo.rb +506 -0
  30. data/examples/dirtree.rb +177 -0
  31. data/examples/newtabbedwindow.rb +100 -0
  32. data/examples/newtesttabp.rb +92 -0
  33. data/examples/tabular.rb +212 -0
  34. data/examples/tasks.rb +179 -0
  35. data/examples/term2.rb +88 -0
  36. data/examples/testbuttons.rb +307 -0
  37. data/examples/testcombo.rb +102 -0
  38. data/examples/testdb.rb +182 -0
  39. data/examples/testfields.rb +208 -0
  40. data/examples/testflowlayout.rb +43 -0
  41. data/examples/testkeypress.rb +98 -0
  42. data/examples/testlistbox.rb +187 -0
  43. data/examples/testlistbox1.rb +199 -0
  44. data/examples/testmessagebox.rb +144 -0
  45. data/examples/testprogress.rb +116 -0
  46. data/examples/testree.rb +107 -0
  47. data/examples/testsplitlayout.rb +53 -0
  48. data/examples/testsplitlayout1.rb +49 -0
  49. data/examples/teststacklayout.rb +48 -0
  50. data/examples/testwsshortcuts.rb +68 -0
  51. data/examples/testwsshortcuts2.rb +129 -0
  52. data/lib/canis.rb +16 -0
  53. data/lib/canis/core/docs/index.txt +104 -0
  54. data/lib/canis/core/docs/list.txt +16 -0
  55. data/lib/canis/core/docs/style_help.yml +34 -0
  56. data/lib/canis/core/docs/tabbedpane.txt +15 -0
  57. data/lib/canis/core/docs/table.txt +31 -0
  58. data/lib/canis/core/docs/textpad.txt +48 -0
  59. data/lib/canis/core/docs/tree.txt +23 -0
  60. data/lib/canis/core/include/.DS_Store +0 -0
  61. data/lib/canis/core/include/action.rb +83 -0
  62. data/lib/canis/core/include/actionmanager.rb +49 -0
  63. data/lib/canis/core/include/appmethods.rb +179 -0
  64. data/lib/canis/core/include/bordertitle.rb +49 -0
  65. data/lib/canis/core/include/canisparser.rb +100 -0
  66. data/lib/canis/core/include/colorparser.rb +437 -0
  67. data/lib/canis/core/include/defaultfilerenderer.rb +64 -0
  68. data/lib/canis/core/include/io.rb +320 -0
  69. data/lib/canis/core/include/layouts/SplitLayout.rb +161 -0
  70. data/lib/canis/core/include/layouts/abstractlayout.rb +213 -0
  71. data/lib/canis/core/include/layouts/flowlayout.rb +104 -0
  72. data/lib/canis/core/include/layouts/stacklayout.rb +109 -0
  73. data/lib/canis/core/include/listbindings.rb +89 -0
  74. data/lib/canis/core/include/listeditable.rb +319 -0
  75. data/lib/canis/core/include/listoperations.rb +61 -0
  76. data/lib/canis/core/include/listselectionmodel.rb +388 -0
  77. data/lib/canis/core/include/multibuffer.rb +173 -0
  78. data/lib/canis/core/include/ractionevent.rb +73 -0
  79. data/lib/canis/core/include/rchangeevent.rb +27 -0
  80. data/lib/canis/core/include/rhistory.rb +95 -0
  81. data/lib/canis/core/include/rinputdataevent.rb +47 -0
  82. data/lib/canis/core/include/textdocument.rb +111 -0
  83. data/lib/canis/core/include/vieditable.rb +175 -0
  84. data/lib/canis/core/include/widgetmenu.rb +66 -0
  85. data/lib/canis/core/system/colormap.rb +165 -0
  86. data/lib/canis/core/system/keydefs.rb +32 -0
  87. data/lib/canis/core/system/ncurses.rb +237 -0
  88. data/lib/canis/core/system/panel.rb +129 -0
  89. data/lib/canis/core/system/window.rb +1081 -0
  90. data/lib/canis/core/util/ansiparser.rb +119 -0
  91. data/lib/canis/core/util/app.rb +696 -0
  92. data/lib/canis/core/util/basestack.rb +412 -0
  93. data/lib/canis/core/util/defaultcolorparser.rb +84 -0
  94. data/lib/canis/core/util/extras/README +5 -0
  95. data/lib/canis/core/util/extras/bottomline.rb +1815 -0
  96. data/lib/canis/core/util/extras/padreader.rb +192 -0
  97. data/lib/canis/core/util/focusmanager.rb +31 -0
  98. data/lib/canis/core/util/helpmanager.rb +160 -0
  99. data/lib/canis/core/util/oldwidgetshortcuts.rb +304 -0
  100. data/lib/canis/core/util/promptmenu.rb +235 -0
  101. data/lib/canis/core/util/rcommandwindow.rb +933 -0
  102. data/lib/canis/core/util/rdialogs.rb +520 -0
  103. data/lib/canis/core/util/textutils.rb +74 -0
  104. data/lib/canis/core/util/viewer.rb +238 -0
  105. data/lib/canis/core/util/widgetshortcuts.rb +508 -0
  106. data/lib/canis/core/widgets/applicationheader.rb +103 -0
  107. data/lib/canis/core/widgets/box.rb +58 -0
  108. data/lib/canis/core/widgets/divider.rb +310 -0
  109. data/lib/canis/core/widgets/extras/README.md +12 -0
  110. data/lib/canis/core/widgets/extras/rtextarea.rb +960 -0
  111. data/lib/canis/core/widgets/extras/stackflow.rb +474 -0
  112. data/lib/canis/core/widgets/keylabelprinter.rb +194 -0
  113. data/lib/canis/core/widgets/listbox.rb +326 -0
  114. data/lib/canis/core/widgets/listfooter.rb +86 -0
  115. data/lib/canis/core/widgets/rcombo.rb +210 -0
  116. data/lib/canis/core/widgets/rcontainer.rb +415 -0
  117. data/lib/canis/core/widgets/rlink.rb +30 -0
  118. data/lib/canis/core/widgets/rmenu.rb +970 -0
  119. data/lib/canis/core/widgets/rmenulink.rb +30 -0
  120. data/lib/canis/core/widgets/rmessagebox.rb +400 -0
  121. data/lib/canis/core/widgets/rprogress.rb +118 -0
  122. data/lib/canis/core/widgets/rtabbedpane.rb +631 -0
  123. data/lib/canis/core/widgets/rtabbedwindow.rb +70 -0
  124. data/lib/canis/core/widgets/rwidget.rb +3634 -0
  125. data/lib/canis/core/widgets/scrollbar.rb +147 -0
  126. data/lib/canis/core/widgets/statusline.rb +113 -0
  127. data/lib/canis/core/widgets/table.rb +1072 -0
  128. data/lib/canis/core/widgets/tabular.rb +264 -0
  129. data/lib/canis/core/widgets/textpad.rb +1674 -0
  130. data/lib/canis/core/widgets/tree.rb +690 -0
  131. data/lib/canis/core/widgets/tree/treecellrenderer.rb +150 -0
  132. data/lib/canis/core/widgets/tree/treemodel.rb +432 -0
  133. data/lib/canis/version.rb +3 -0
  134. metadata +229 -0
@@ -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,16 @@
1
+ 1. simplify %Field. datatype and mask is overlapping
2
+ 1. simplify %field, two ways of creating a label
3
+ 2. how to override +- * a and others for listbox - need to call before super()
4
+ 3. clear_row in %textpad can overlap next row if data long
5
+ 4. app to contain window close and confirm close
6
+ 4. %menu - remove complex rare functionality from main code
7
+ 4. redo %menu bar -- current code is old and messy
8
+ 5. test out vieditable and listeditable with core
9
+ 6. when sorting cursor on old row but curr changed
10
+ .3. Make keylabels more rubyesque - later
11
+ x1. check native_text again to see how much used
12
+ x2. Show key mappings to user
13
+ x3. row_selector to be v
14
+ x5. convert testlistbox to core
15
+ x5. messagebox default button - done but current button should show default char
16
+ 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,506 @@
1
+ require 'canis/core/util/app'
2
+ require 'sqlite3'
3
+ #require 'canis/experimental/resultsettextview.rb'
4
+ #require 'canis/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
+ fields = "*" if fields == ""
66
+ stmt = "select #{fields} from #{name}"
67
+ stmt << $where_string if $where_string
68
+ stmt << $order_string if $order_string
69
+ view_sql stmt
70
+ @form.by_name['tarea'] << stmt if @form # nil when called from menu
71
+ end
72
+ def view_sql stmt
73
+ begin
74
+ content = get_data stmt
75
+ if content.nil?
76
+ else
77
+ require 'canis/core/widgets/tabular'
78
+ t = Tabular.new do |t|
79
+ t.headings = $columns
80
+ t.data=content
81
+ end
82
+ view t.render
83
+ end
84
+ rescue => err
85
+ $log.error err.to_s
86
+ $log.error(err.backtrace.join("\n"))
87
+ textdialog [err.to_s, *err.backtrace], :title => "Exception"
88
+ end
89
+ end
90
+
91
+ App.new do
92
+ #header = app_header "canis #{Canis::VERSION}", :text_center => "Database Demo", :text_right =>"enabled"
93
+ form = @form
94
+ mylabel = "a field"
95
+ $catch_alt_digits = true # use M-1..9 in textarea
96
+ $current_table = nil
97
+ $current_db = nil # "testd.db"
98
+ connect $current_db if $current_db
99
+ def which_field
100
+ alert "curent field is #{form.get_current_field} "
101
+ end
102
+
103
+ def get_commands
104
+ %w{ which_field }
105
+ end
106
+ def help_text
107
+ <<-eos
108
+ DBDEMO HELP
109
+
110
+ This is some help text for dbdemo.
111
+ We are testing out this feature.
112
+
113
+ Alt-d - Select a database
114
+ <Enter> on a table, view data (q to close window)
115
+ v on a table, display columns in lower list
116
+
117
+ COLUMN LIST KEYS
118
+ v on a column for multiple select
119
+ V on a column for range select/deselect from previous selection
120
+ <Enter> on column table to view data for selected columns
121
+ u unselect all
122
+ a select all
123
+ * invert selection
124
+ F4 View data for selected table (or columns if selected)
125
+
126
+ q or C-q Close the data window that comes on Enter or F4
127
+
128
+ Alt-x - Command mode (<tab> to see commands and select)
129
+ : - Command mode
130
+ Alt-z - Commands in TextArea
131
+
132
+ Sql Entry Area
133
+ C-x e Edit in $EDITOR or vi
134
+ M-? To see other key-bindings
135
+ F4 Execute SQL (there should be only one sql).
136
+
137
+
138
+ Result Set (this is not present in this demo any longer - moved
139
+ to canis-extras)
140
+ , Prev row (mnemonic <)
141
+ . Next row (mnemonic >)
142
+ < First row
143
+ > Last row
144
+
145
+ F10 - Quit application
146
+ [[index]]
147
+
148
+
149
+
150
+ -----------------------------------------------------------------------
151
+ Hope you enjoyed this help.
152
+ eos
153
+ end
154
+ def ask_databases
155
+ names = Dir.glob("*.{sqlite,db}")
156
+ if names
157
+ ix = popuplist( names )
158
+ if ix
159
+ value = names[ix]
160
+ connect(value);
161
+ @form.by_name["tlist"].list(get_table_names)
162
+ end
163
+
164
+ else
165
+ alert "Can't find a .db or .sqlite file"
166
+ end
167
+ end
168
+ @form.help_manager.help_text = help_text()
169
+ # TODO accelerators and
170
+ # getting a handle for later use
171
+ mb = menubar do
172
+ keep_visible true
173
+ #@toggle_key=KEY_F2
174
+ menu "File" do
175
+ item "Open", "O" do
176
+ accelerator "Ctrl-O"
177
+ command do
178
+ alert "HA!! you wanted to open a file?"
179
+ end
180
+ end
181
+ menu "Database" do
182
+ item_list do
183
+ Dir.glob("**/*.{sqlite,db}")
184
+ end
185
+ command do |menuitem, text|
186
+ connect text
187
+ form.by_name["tlist"].list(get_table_names)
188
+ end
189
+ end
190
+ menu "Tables" do
191
+ item_list do
192
+ if $current_db
193
+ get_table_names
194
+ end
195
+ end
196
+ command do |menuitem, text|
197
+ $current_table = text
198
+ #alert(get_column_names(text).join(", "))
199
+ create_popup(get_column_names(text), :multiple) { |value| view_data( text, value.join(",") ) }
200
+ end
201
+ end
202
+ item "New", "N"
203
+ separator
204
+ item "Exit", "x" do
205
+ command do
206
+ throw(:close)
207
+ end
208
+ end
209
+ item "Cancel Menu" do
210
+ accelerator "Ctrl-g"
211
+ end
212
+
213
+ end # menu
214
+ menu "Window" do
215
+ item "Tile", "T"
216
+ menu "Find" do
217
+ item "More", "M"
218
+ $x = item "Less", "L" do
219
+ #accelerator "Ctrl-X"
220
+ command do
221
+ alert "You clickses on Less"
222
+ end
223
+ end
224
+ menu "Size" do
225
+ item "Zoom", "Z"
226
+ item "Maximize", "X"
227
+ item "Minimize", "N"
228
+ end
229
+ end
230
+ end
231
+ menu "Others" do
232
+ require 'canis/core/include/appmethods.rb'
233
+ item "Shell Output" do
234
+ command { shell_output }
235
+ end
236
+ item "Suspend" do
237
+ command { suspend }
238
+ end
239
+ end
240
+ end # menubar
241
+ mb.toggle_key = FFI::NCurses::KEY_F2
242
+ mb.color = :white
243
+ mb.bgcolor = :blue
244
+ @form.set_menu_bar mb
245
+ tv = nil
246
+ flow :margin_top => 1 do
247
+ col1w = 20
248
+ stack :width_pc => 20 do
249
+ text = ["No tables"]
250
+ if !$current_db
251
+ text = ["Select DB first.","Press Alt-D or ENTER"]
252
+ end
253
+ tlist = listbox :name => "tlist", :list => text, :title => "Tables", :height => 10,
254
+ :selected_color => 'cyan', :selected_bgcolor => 'black' , :selected_attr => Ncurses::A_REVERSE,
255
+ :help_text => "<ENTER> to View complete table, 'v' to select table and view columns",
256
+ :should_show_focus => true,
257
+ :selection_mode => :single
258
+ tlist.bind(:PRESS) do |eve|
259
+ if $current_db
260
+ # get data of table
261
+ view_data eve.text
262
+ #tv.sqlite $current_db, eve.text, "select * from #{eve.text} " # TODO in core
263
+ else
264
+ ask_databases
265
+ end
266
+ end
267
+ #tlist.bind(:ENTER_ROW) do |eve|
268
+ # too much confusion between selected and focussed row
269
+ #$current_table = eve.text if $db
270
+ #end
271
+ clist = listbox :name => "clist", :list => ["No columns"], :title => "Columns", :height => 14,
272
+ :selection_mode => :multiple,
273
+ :selected_color => 'cyan', :selected_bgcolor => 'black' , :selected_attr => Ncurses::A_REVERSE,
274
+ :help_text => "Enter to View selected fields, 'v' to select columns, w - where, o-order"
275
+ tlist.bind(:LIST_SELECTION_EVENT) do |eve|
276
+ $selected_table = eve.source[eve.firstrow]
277
+ $current_table = $selected_table
278
+ clist.list( get_column_names $selected_table)
279
+ end
280
+ clist.bind(:PRESS) do |eve|
281
+ # get data of table
282
+ if $selected_table
283
+ cols = "*"
284
+ c = clist.values_at(*clist.selected_indices)
285
+ c = clist.selected_values
286
+ unless c.empty?
287
+ cols = c.join(",")
288
+ end
289
+ view_data $selected_table, cols
290
+ else
291
+ alert "Select a table first."
292
+ end
293
+ end
294
+ clist.bind_key('w', 'add to where condition') {
295
+ c = clist.current_value
296
+ $where_columns ||= []
297
+ hist = ["#{c} = "]
298
+ w = rb_gets("where "){ |q| q.default = "#{c} = "; q.history = hist }
299
+ $where_columns << w if w
300
+ message "where: #{$where_columns.last}. Press F4 when done"
301
+ $log.debug "XXX: WHERE: #{$where_columns} "
302
+ }
303
+ clist.bind_key('o', 'add to order by') {
304
+ c = clist.current_value
305
+ $order_columns ||= []
306
+ $order_columns << c if c
307
+ message "order (asc): #{$order_columns.last}. Press F4 when done"
308
+ $log.debug "XXX: ORDER: #{$order_columns} "
309
+ }
310
+ clist.bind_key('O', 'add to ordery by desc') {
311
+ c = clist.current_value
312
+ $order_columns ||= []
313
+ $order_columns << " #{c} desc " if c
314
+ message "order: #{$order_columns.last}"
315
+ $log.debug "XXX: ORDER: #{$order_columns}. Press F4 when done"
316
+ }
317
+ @statusline = status_line
318
+ #wg = get_color($datacolor, 'white','green')
319
+ #wb = get_color($datacolor, 'white','blue')
320
+ @statusline.command {
321
+ # trying this out. If you want a persistent message that remains till the next on
322
+ # then send it in as $status_message
323
+ text = $status_message.value || ""
324
+ if !$current_db
325
+ #"[%-s] %s" % [ "Select a Database", text]
326
+ "[%-s] %s" % [ "#[bg=red,fg=yellow]Select a Database#[end]", text]
327
+ #[ [nil, "%-22s" % Time.now, nil], [$errorcolor, " [Select a Database ]", FFI::NCurses::A_BOLD], [nil, text, nil] ]
328
+ elsif !$current_table
329
+ "[DB: #[fg=white,bg=blue]%-s#[end] | %-s ] %s" % [ $current_db || "None", $current_table || "#[bg=red,fg=yellow]Select a table#[end]", text]
330
+ #[ [nil, "%-22s [DB: %-s | " % [Time.now, $current_db || "None" ],nil], [$errorcolor, " Select a Table ]", FFI::NCurses::A_BOLD], [nil, text, nil] ]
331
+ else
332
+ "DB: #[fg=white,bg=green,bold]%-s#[end] | #[bold]%-s#[end] ] %s" % [ $current_db || "None", $current_table || "----", text]
333
+ #[ [nil, "%-22s [DB: " % Time.now, nil], [wb, " #{$current_db} ", FFI::NCurses::A_BOLD],
334
+ #[wg, $current_table || "----", FFI::NCurses::A_BOLD], [nil, text, nil] ]
335
+ end
336
+ }
337
+ @adock = nil
338
+ keyarray = [
339
+ ["F1" , "Help"], ["F10" , "Exit"],
340
+ ["F2", "Menu"], ["F4", "View"],
341
+ ["M-d", "Database"], ["M-t", "Table"],
342
+ ["M-x", "Command"], nil
343
+ ]
344
+ tlist_keyarray = keyarray + [ ["Sp", "Select"], nil, ["Enter","View"] ]
345
+
346
+ clist_keyarray = keyarray + [ ["Sp", "Select"], ["C-sp", "Range Sel"],
347
+ ["Enter","View"], ['w', 'where'],
348
+ ["o","order by"], ['O', 'order desc']
349
+ ]
350
+ tarea_keyarray = keyarray + [ ["M-z", "Commands"], nil ]
351
+ #tarea_sub_keyarray = [ ["r", "Run"], ["c", "clear"], ["w","Save"], ["a", "Append next"],
352
+ #["y", "Yank"], ["Y", "yank pop"] ]
353
+ tarea_sub_keyarray = [ ["r", "Run"], ["c", "clear"], ["e", "Edit externally"], ["w","Kill Ring Save (M-w)"], ["a", "Append Next"],
354
+ ["y", "Yank (C-y)"], ["Y", "yank pop (M-y)"],
355
+ ["u", "Undo (C-_)"], ["R", "Redo (C-r)"],
356
+ ]
357
+
358
+ gw = get_color($reversecolor, 'green', 'black')
359
+ @adock = dock keyarray, { :row => Ncurses.LINES-2, :footer_color_pair => $datacolor,
360
+ :footer_mnemonic_color_pair => gw }
361
+ @adock.set_key_labels tlist_keyarray, :tables
362
+ @adock.set_key_labels clist_keyarray, :columns
363
+ @adock.set_key_labels tarea_sub_keyarray, :tarea_sub
364
+ @adock.set_key_labels tarea_keyarray, :tarea
365
+ tlist.bind(:ENTER) { @adock.mode :tables }
366
+ clist.bind(:ENTER) { @adock.mode :columns }
367
+
368
+ reduce = lambda { |obj|
369
+ obj.height -= 1 if obj.height > 3
370
+ }
371
+ increase = lambda { |obj|
372
+ obj.height += 1 if obj.height + obj.row < Ncurses.LINES-2
373
+ }
374
+ _lower = lambda { |obj|
375
+ obj.row += 1 if obj.height + obj.row < Ncurses.LINES-2
376
+ }
377
+ _raise = lambda { |obj|
378
+ obj.row -= 1 if obj.row > 2
379
+ }
380
+ [clist, tlist].each do |o|
381
+ o.bind_key([?\C-x, ?-]){ |o| reduce.call(o) }
382
+ o.bind_key([?\C-x, ?+]){ |o| increase.call(o) }
383
+ o.bind_key([?\C-x, ?v]){ |o| _lower.call(o) }
384
+ o.bind_key([?\C-x, ?6]){ |o| _raise.call(o) }
385
+ end
386
+
387
+
388
+ @form.bind_key([?q,?q], 'quit') { throw :close }
389
+ @form.bind_key(?\M-t, 'select table') do
390
+ if $current_db.nil?
391
+ alert "Please select database first"
392
+ else
393
+ create_popup( get_table_names,:single) {|value| $selected_table = $current_table = value}
394
+ end
395
+ end
396
+ @form.bind_key(?\M-d, 'select database') do
397
+ ask_databases
398
+ end
399
+ @form.bind_key(FFI::NCurses::KEY_F4, 'view data') do
400
+ $where_string = nil
401
+ $order_string = nil
402
+ if $where_columns
403
+ $where_string = " where " + $where_columns.join(" and ")
404
+ end
405
+ if $order_columns
406
+ $order_string = " order by " + $order_columns.join(" , ")
407
+ end
408
+ # mismatch between current and selected table
409
+ if $current_table
410
+ cols = "*"
411
+ #c = clist.get_selected_values
412
+ c = clist.values_at(*clist.selected_indices)
413
+ unless c.empty?
414
+ cols = c.join(",")
415
+ end
416
+ view_data $current_table, cols
417
+ else
418
+ alert "Select a table first."
419
+ end
420
+ end
421
+ end # stack
422
+ stack :width_pc => 80 do
423
+ tarea = textarea :name => 'tarea', :height => 5, :title => 'Sql Statement'
424
+ #undom = SimpleUndo.new tarea
425
+ tarea.bind_key(Ncurses::KEY_F4, 'view data') do
426
+ text = tarea.get_text
427
+ if text == ""
428
+ alert "Please enter a query and then hit F4. Or press F4 over column list"
429
+ else
430
+ view_sql tarea.get_text
431
+ end
432
+ end
433
+ tarea.bind(:ENTER) { @adock.mode :tarea }
434
+ tarea.bind_key(?\M-z, 'textarea submenu'){
435
+
436
+ hash = { 'c' => lambda{ tarea.remove_all },
437
+ 'e' => lambda{ tarea.edit_external },
438
+ 'w' => lambda{ tarea.kill_ring_save },
439
+ 'a' => lambda{ tarea.append_next_kill },
440
+ 'y' => lambda{ tarea.yank },
441
+ 'Y' => lambda{ tarea.yank_pop },
442
+ 'r' => lambda{ view_sql tarea.get_text },
443
+ 'u' => lambda{ tarea.undo },
444
+ 'R' => lambda{ tarea.redo },
445
+ }
446
+
447
+
448
+ @adock.mode :tarea_sub
449
+ @adock.repaint
450
+ keys = @adock.get_current_keys
451
+ while((ch = @window.getchar()) != ?\C-c.getbyte(0) )
452
+ if ch < 33 || ch > 126
453
+ Ncurses.beep
454
+ elsif !keys.include?(ch.chr)
455
+ Ncurses.beep
456
+ else
457
+ hash.fetch(ch.chr).call
458
+ #opt_file ch.chr
459
+ break
460
+ end
461
+ end
462
+ @adock.mode :normal
463
+ } # M-z
464
+ flow do
465
+ #button_row = 17
466
+ button "Save" do
467
+ @cmd_history ||= []
468
+ filename = rb_gets("File to append contents to: ") { |q| q.default = @oldfilename; q.history = @cmd_history }
469
+
470
+ if filename
471
+ str = tarea.get_text
472
+ File.open(filename, 'a') {|f| f.write(str) }
473
+ @oldfilename = filename
474
+ @cmd_history << filename unless @cmd_history.include? filename
475
+
476
+ message "Appended data to #{filename}"
477
+ else
478
+ message "Aborted operation"
479
+ end
480
+ #hide_bottomline
481
+ end
482
+ button "Read" do
483
+ filter = "*"
484
+ #str = choose filter, :title => "Files", :prompt => "Choose a file: "
485
+ cproc = Proc.new { |str| Dir.glob(str + "*") }
486
+ str = rb_gets "Choose a file: ", :title => "Files", :tab_completion => cproc,
487
+ :help_text => "Press <tab> to complete filenames. C-a, C-e, C-k. Alt-?"
488
+ if str && File.exists?(str)
489
+ begin
490
+ tarea.set_content(str)
491
+ message "Read content from #{str} "
492
+ rescue => err
493
+ print_error_message "No file named: #{str}: #{err.to_s} "
494
+ end
495
+ end
496
+ end
497
+ #ok_button = button( [button_row,30], "OK", {:mnemonic => 'O'}) do
498
+ #end
499
+ end
500
+ blank
501
+ #tv = Canis::ResultsetTextView.new @form, :row => 1, :col => 1, :width => 50, :height => 16
502
+ #tv = resultsettextview :name => 'resultset', :height => 18 , :title => 'DB Browser', :print_footer => true
503
+
504
+ end
505
+ end
506
+ end # app