rkumar-rbcurse 0.1.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.
- data/CHANGELOG +1577 -0
- data/README.txt +310 -0
- data/examples/qdfilechooser.rb +68 -0
- data/examples/rfe.rb +853 -0
- data/examples/rfe_renderer.rb +69 -0
- data/examples/test1.rb +242 -0
- data/examples/test2.rb +498 -0
- data/examples/testcombo.rb +95 -0
- data/examples/testkeypress.rb +61 -0
- data/examples/testmenu.rb +105 -0
- data/examples/testtable.rb +266 -0
- data/examples/testtabp.rb +106 -0
- data/examples/testtodo.rb +532 -0
- data/examples/viewtodo.rb +512 -0
- data/lib/rbcurse.rb +7 -0
- data/lib/rbcurse/action.rb +31 -0
- data/lib/rbcurse/applicationheader.rb +57 -0
- data/lib/rbcurse/celleditor.rb +120 -0
- data/lib/rbcurse/checkboxcellrenderer.rb +69 -0
- data/lib/rbcurse/colormap.rb +133 -0
- data/lib/rbcurse/comboboxcellrenderer.rb +45 -0
- data/lib/rbcurse/defaultlistselectionmodel.rb +49 -0
- data/lib/rbcurse/keylabelprinter.rb +143 -0
- data/lib/rbcurse/listcellrenderer.rb +99 -0
- data/lib/rbcurse/listkeys.rb +33 -0
- data/lib/rbcurse/listscrollable.rb +216 -0
- data/lib/rbcurse/listselectable.rb +67 -0
- data/lib/rbcurse/mapper.rb +108 -0
- data/lib/rbcurse/orderedhash.rb +77 -0
- data/lib/rbcurse/rcombo.rb +243 -0
- data/lib/rbcurse/rdialogs.rb +183 -0
- data/lib/rbcurse/rform.rb +845 -0
- data/lib/rbcurse/rinputdataevent.rb +36 -0
- data/lib/rbcurse/rlistbox.rb +804 -0
- data/lib/rbcurse/rmenu.rb +666 -0
- data/lib/rbcurse/rmessagebox.rb +325 -0
- data/lib/rbcurse/rpopupmenu.rb +754 -0
- data/lib/rbcurse/rtabbedpane.rb +259 -0
- data/lib/rbcurse/rtable.rb +1296 -0
- data/lib/rbcurse/rtextarea.rb +673 -0
- data/lib/rbcurse/rtextview.rb +335 -0
- data/lib/rbcurse/rwidget.rb +1731 -0
- data/lib/rbcurse/scrollable.rb +301 -0
- data/lib/rbcurse/selectable.rb +94 -0
- data/lib/rbcurse/table/tablecellrenderer.rb +85 -0
- data/lib/rbcurse/table/tabledatecellrenderer.rb +102 -0
- data/lib/ver/keyboard.rb +150 -0
- data/lib/ver/keyboard2.rb +170 -0
- data/lib/ver/ncurses.rb +102 -0
- data/lib/ver/window.rb +369 -0
- data/test/test_rbcurse.rb +0 -0
- metadata +117 -0
@@ -0,0 +1,512 @@
|
|
1
|
+
$LOAD_PATH << "/Users/rahul/work/projects/rbcurse/"
|
2
|
+
require 'rubygems'
|
3
|
+
require 'ncurses'
|
4
|
+
require 'logger'
|
5
|
+
#require 'ver/keyboard'
|
6
|
+
require 'rbcurse'
|
7
|
+
require 'rbcurse/rcombo'
|
8
|
+
require 'rbcurse/rtable'
|
9
|
+
#require 'rbcurse/table/tablecellrenderer'
|
10
|
+
require 'rbcurse/keylabelprinter'
|
11
|
+
require 'rbcurse/applicationheader'
|
12
|
+
require 'rbcurse/action'
|
13
|
+
|
14
|
+
class TodoList
|
15
|
+
def initialize file
|
16
|
+
@file = file
|
17
|
+
end
|
18
|
+
def load
|
19
|
+
@todomap = YAML::load(File.open(@file));
|
20
|
+
@records = convert_to_text
|
21
|
+
end
|
22
|
+
def get_statuses
|
23
|
+
@todomap['__STATUSES']
|
24
|
+
end
|
25
|
+
def get_modules
|
26
|
+
@todomap['__MODULES'].sort
|
27
|
+
end
|
28
|
+
def get_categories
|
29
|
+
@todomap.keys.delete_if {|k| k.match(/^__/) }
|
30
|
+
end
|
31
|
+
def get_tasks_for_category categ
|
32
|
+
c = @todomap[categ]
|
33
|
+
d = []
|
34
|
+
c.each_pair {|k,v|
|
35
|
+
v.each do |r|
|
36
|
+
row=[]
|
37
|
+
row << k
|
38
|
+
r.each { |r1| row << r1 }
|
39
|
+
d << row
|
40
|
+
#$log.debug " ROW = #{row.inspect} "
|
41
|
+
end
|
42
|
+
}
|
43
|
+
return d
|
44
|
+
end
|
45
|
+
def get_records_for_category categ
|
46
|
+
if categ.nil? or categ == ""
|
47
|
+
return @records
|
48
|
+
else
|
49
|
+
return @records.select { |row| row[0] == categ }
|
50
|
+
end
|
51
|
+
end
|
52
|
+
def sort categ, column, descending=false
|
53
|
+
d = get_records_for_category categ
|
54
|
+
d = d.sort { |y,x|
|
55
|
+
if descending
|
56
|
+
if x[column].nil?
|
57
|
+
$log.debug "sort -1"
|
58
|
+
-1
|
59
|
+
elsif y[column].nil?
|
60
|
+
$log.debug "sort 1"
|
61
|
+
1
|
62
|
+
else
|
63
|
+
$log.debug "sort <> #{x[column]} <=> #{y[column]} "
|
64
|
+
x[column] <=> y[column]
|
65
|
+
end
|
66
|
+
else
|
67
|
+
if x[column].nil?
|
68
|
+
1
|
69
|
+
elsif y[column].nil?
|
70
|
+
-1
|
71
|
+
else
|
72
|
+
y[column] <=> x[column]
|
73
|
+
end
|
74
|
+
end
|
75
|
+
}
|
76
|
+
return d
|
77
|
+
end
|
78
|
+
def set_tasks_for_category categ, data
|
79
|
+
d = {}
|
80
|
+
data.each do |row|
|
81
|
+
#key = row.delete_at 0
|
82
|
+
key = row.first
|
83
|
+
d[key] ||= []
|
84
|
+
d[key] << row[1..-1]
|
85
|
+
end
|
86
|
+
@todomap[categ]=d
|
87
|
+
$log.debug " NEW DATA #{categ}: #{data}"
|
88
|
+
end
|
89
|
+
def convert_to_text
|
90
|
+
d = []
|
91
|
+
cats = get_categories
|
92
|
+
cats.each do |c|
|
93
|
+
tasks = get_tasks_for_category c
|
94
|
+
tasks.each do |t|
|
95
|
+
n = t.dup
|
96
|
+
n.insert 0, c
|
97
|
+
d << n
|
98
|
+
end
|
99
|
+
end
|
100
|
+
return d
|
101
|
+
end
|
102
|
+
=begin
|
103
|
+
File.open("todo.csv", "w") { |f| YAML.dump( d, f )}
|
104
|
+
buf =''
|
105
|
+
require 'csv'
|
106
|
+
CSV.open('todocsv.csv', 'w') do |writer|
|
107
|
+
#writer << [nil, nil]
|
108
|
+
d.each do |row|
|
109
|
+
#parced_cells = CSV.generate_rows(row, row.size, buf)
|
110
|
+
writer << row
|
111
|
+
end
|
112
|
+
end
|
113
|
+
=end
|
114
|
+
def dump
|
115
|
+
f = "#{@file}"
|
116
|
+
#File.open(f, "w") { |f| YAML.dump( @todomap, f )}
|
117
|
+
convert_to_text
|
118
|
+
end
|
119
|
+
end
|
120
|
+
def get_key_labels
|
121
|
+
key_labels = [
|
122
|
+
['C-q', 'Exit'], nil,
|
123
|
+
['M-c', 'Category'], nil,
|
124
|
+
['M-f', 'Filter Fld'], ['M-p', 'Pattern'],
|
125
|
+
['M-s', 'Sort'], ['M-i', 'Filter']
|
126
|
+
]
|
127
|
+
return key_labels
|
128
|
+
end
|
129
|
+
def get_key_labels_table
|
130
|
+
key_labels = [
|
131
|
+
['M-n','NewRow'], ['M-d','DelRow'],
|
132
|
+
['C-x','Select'], nil,
|
133
|
+
['M-0', 'Top'], ['M-9', 'End'],
|
134
|
+
['C-p', 'PgUp'], ['C-n', 'PgDn'],
|
135
|
+
['M-Tab','Nxt Fld'], ['Tab','Nxt Col'],
|
136
|
+
['+','Widen'], ['-','Narrow']
|
137
|
+
]
|
138
|
+
return key_labels
|
139
|
+
end
|
140
|
+
class TodoApp
|
141
|
+
def initialize
|
142
|
+
@window = VER::Window.root_window
|
143
|
+
@form = Form.new @window
|
144
|
+
@sort_dir = true
|
145
|
+
|
146
|
+
@todo = TodoList.new "todo.yml"
|
147
|
+
@todo.load
|
148
|
+
end
|
149
|
+
def run
|
150
|
+
todo = @todo
|
151
|
+
statuses = todo.get_statuses
|
152
|
+
cats = todo.get_categories
|
153
|
+
cats.insert 0,""
|
154
|
+
modules = todo.get_modules
|
155
|
+
title = "TODO APP"
|
156
|
+
@header = ApplicationHeader.new @form, title, {:text2=>"Some Text", :text_center=>"Task View"}
|
157
|
+
status_row = RubyCurses::Label.new @form, {'text' => "", :row => Ncurses.LINES-4, :col => 0, :display_length=>60}
|
158
|
+
@status_row = status_row
|
159
|
+
# setting ENTER across all objects on a form
|
160
|
+
@form.bind(:ENTER) {|f| status_row.text = f.help_text unless f.help_text.nil? }
|
161
|
+
#@window.printstring 0,(Ncurses.COLS-title.length)/2,title, $datacolor
|
162
|
+
r = 1; c = 1;
|
163
|
+
categ = ComboBox.new @form do
|
164
|
+
name "categ"
|
165
|
+
row r
|
166
|
+
col 15
|
167
|
+
display_length 10
|
168
|
+
editable false
|
169
|
+
list cats
|
170
|
+
set_label Label.new @form, {'text' => "Category", 'color'=>'cyan','col'=>1, "mnemonic"=>"C"}
|
171
|
+
list_config 'height' => 4
|
172
|
+
help_text "Select a category and <TAB> out. KEY_UP, KEY_DOWN, M-Down"
|
173
|
+
end
|
174
|
+
colnames = %w[ Categ Module Prior Task Status Date]
|
175
|
+
|
176
|
+
colnames_cbl = colnames.dup
|
177
|
+
colnames_cbl.insert 0, ""
|
178
|
+
col_combo = ComboBox.new @form do
|
179
|
+
name "col_combo"
|
180
|
+
row r
|
181
|
+
col 45
|
182
|
+
display_length 10
|
183
|
+
editable false
|
184
|
+
list colnames_cbl
|
185
|
+
set_label Label.new @form, {'text' => "Filter on:", 'color'=>'cyan',"mnemonic"=>"F"}
|
186
|
+
list_config 'height' => 6
|
187
|
+
help_text "Select a field to filter on"
|
188
|
+
end
|
189
|
+
col_value = Field.new @form do
|
190
|
+
name "col_value"
|
191
|
+
row r+1
|
192
|
+
col 45
|
193
|
+
bgcolor 'cyan'
|
194
|
+
color 'white'
|
195
|
+
display_length 10
|
196
|
+
set_label Label.new @form, {'text' => "Pattern:", 'color'=>'cyan',:bgcolor => 'black',"mnemonic"=>"P"}
|
197
|
+
help_text "Pattern/Regex to filter on"
|
198
|
+
end
|
199
|
+
data = todo.get_records_for_category 'TODO'
|
200
|
+
@data = data
|
201
|
+
b_filter = Button.new @form do
|
202
|
+
text "Fi<er"
|
203
|
+
row r
|
204
|
+
col 65
|
205
|
+
help_text "Filter on selected filter column and value"
|
206
|
+
#bind(:ENTER) { status_row.text "New button adds a new row below current " }
|
207
|
+
end
|
208
|
+
|
209
|
+
|
210
|
+
table_ht = 15
|
211
|
+
atable = Table.new @form do
|
212
|
+
name "tasktable"
|
213
|
+
row r+2
|
214
|
+
col c
|
215
|
+
width 104
|
216
|
+
height table_ht
|
217
|
+
#title "A Table"
|
218
|
+
#title_attrib (Ncurses::A_REVERSE | Ncurses::A_BOLD)
|
219
|
+
cell_editing_allowed false
|
220
|
+
set_data data, colnames
|
221
|
+
end
|
222
|
+
@atable = atable
|
223
|
+
categ.bind(:CHANGED) do |fld| $log.debug " COMBO EXIT XXXXXXXX";
|
224
|
+
data = todo.get_records_for_category fld.getvalue;
|
225
|
+
@data = data
|
226
|
+
atable.table_model.data = data
|
227
|
+
end
|
228
|
+
b_filter.command {
|
229
|
+
alert("Data is blank") if data.nil? or data.size == 0
|
230
|
+
raise("Data is blank") if data.nil? or data.size == 0
|
231
|
+
raise("selected is blank") if col_combo.selected_item.nil?
|
232
|
+
raise("col_val is blank") if col_value.getvalue.nil?
|
233
|
+
|
234
|
+
$log.debug "#{col_combo.selected_index}, .#{col_value.getvalue}"
|
235
|
+
d = data.select {|row| row[col_combo.selected_index-1].to_s.match(col_value.getvalue) }
|
236
|
+
atable.table_model.data = d unless d.nil? or d.size == 0
|
237
|
+
}
|
238
|
+
|
239
|
+
tcm = atable.get_table_column_model
|
240
|
+
#
|
241
|
+
## key bindings fo atable
|
242
|
+
# column widths
|
243
|
+
tcm.column(0).width 8
|
244
|
+
tcm.column(1).width 8
|
245
|
+
tcm.column(2).width 5
|
246
|
+
tcm.column(3).width 50
|
247
|
+
tcm.column(4).width 8
|
248
|
+
tcm.column(5).width 16
|
249
|
+
app = self
|
250
|
+
atable.configure() do
|
251
|
+
#bind_key(330) { atable.remove_column(tcm.column(atable.focussed_col)) rescue "" }
|
252
|
+
bind_key(?+) {
|
253
|
+
acolumn = atable.column atable.focussed_col()
|
254
|
+
w = acolumn.width + 1
|
255
|
+
acolumn.width w
|
256
|
+
#atable.table_structure_changed
|
257
|
+
}
|
258
|
+
bind_key(?-) {
|
259
|
+
acolumn = atable.column atable.focussed_col()
|
260
|
+
w = acolumn.width - 1
|
261
|
+
if w > 3
|
262
|
+
acolumn.width w
|
263
|
+
#atable.table_structure_changed
|
264
|
+
end
|
265
|
+
}
|
266
|
+
bind_key(?>) {
|
267
|
+
colcount = tcm.column_count-1
|
268
|
+
#atable.move_column sel_col.value, sel_col.value+1 unless sel_col.value == colcount
|
269
|
+
col = atable.focussed_col
|
270
|
+
atable.move_column col, col+1 unless col == colcount
|
271
|
+
}
|
272
|
+
bind_key(?<) {
|
273
|
+
col = atable.focussed_col
|
274
|
+
atable.move_column col, col-1 unless col == 0
|
275
|
+
#atable.move_column sel_col.value, sel_col.value-1 unless sel_col.value == 0
|
276
|
+
}
|
277
|
+
bind_key(?\M-h, app) {|tab,td| $log.debug " BIND... #{tab.class}, #{td.class}"; app.make_popup atable}
|
278
|
+
end
|
279
|
+
#keylabel = RubyCurses::Label.new @form, {'text' => "", "row" => r+table_ht+3, "col" => c, "color" => "yellow", "bgcolor"=>"blue", "display_length"=>60, "height"=>2}
|
280
|
+
#eventlabel = RubyCurses::Label.new @form, {'text' => "Events:", "row" => r+table_ht+6, "col" => c, "color" => "white", "bgcolor"=>"blue", "display_length"=>60, "height"=>2}
|
281
|
+
|
282
|
+
# report some events
|
283
|
+
#atable.table_model.bind(:TABLE_MODEL_EVENT){|e| #eventlabel.text = "Event: #{e}"}
|
284
|
+
#atable.get_table_column_model.bind(:TABLE_COLUMN_MODEL_EVENT){|e| eventlabel.text = "Event: #{e}"}
|
285
|
+
atable.bind(:TABLE_TRAVERSAL_EVENT){|e| @header.text_right "Row #{e.newrow+1} of #{atable.row_count}" }
|
286
|
+
|
287
|
+
|
288
|
+
#str_renderer = TableCellRenderer.new ""
|
289
|
+
#num_renderer = TableCellRenderer.new "", { "justify" => :right }
|
290
|
+
#bool_renderer = CheckBoxCellRenderer.new "", {"parent" => atable, "display_length"=>5}
|
291
|
+
#combo_renderer = RubyCurses::ComboBoxCellRenderer.new nil, {"parent" => atable, "display_length"=> 8}
|
292
|
+
#combo_editor = RubyCurses::CellEditor.new(RubyCurses::ComboBox.new nil, {"focusable"=>false, "visible"=>false, "list"=>statuses, "display_length"=>8})
|
293
|
+
#combo_editor1 = RubyCurses::CellEditor.new(RubyCurses::ComboBox.new nil, {"focusable"=>false, "visible"=>false, "list"=>modules, "display_length"=>8})
|
294
|
+
#atable.set_default_cell_renderer_for_class "String", str_renderer
|
295
|
+
#atable.set_default_cell_renderer_for_class "Fixnum", num_renderer
|
296
|
+
#atable.set_default_cell_renderer_for_class "Float", num_renderer
|
297
|
+
#atable.set_default_cell_renderer_for_class "TrueClass", bool_renderer
|
298
|
+
#atable.set_default_cell_renderer_for_class "FalseClass", bool_renderer
|
299
|
+
#atable.get_table_column_model.column(3).cell_editor = combo_editor
|
300
|
+
#atable.get_table_column_model.column(0).cell_editor = combo_editor1
|
301
|
+
#ce = atable.get_default_cell_editor_for_class "String"
|
302
|
+
# increase the maxlen of task
|
303
|
+
#ce.component.maxlen = 80
|
304
|
+
# I want up and down to go up and down rows inside the combo box, i can use M-down for changing.
|
305
|
+
#combo_editor.component.unbind_key(KEY_UP)
|
306
|
+
#combo_editor.component.unbind_key(KEY_DOWN)
|
307
|
+
#combo_editor1.component.unbind_key(KEY_UP)
|
308
|
+
#combo_editor1.component.unbind_key(KEY_DOWN)
|
309
|
+
buttrow = r+table_ht+8 #Ncurses.LINES-4
|
310
|
+
buttrow = Ncurses.LINES-5
|
311
|
+
create_table_actions atable, todo, data, categ.getvalue
|
312
|
+
=begin
|
313
|
+
b_newrow = Button.new @form do
|
314
|
+
text "&New"
|
315
|
+
row buttrow
|
316
|
+
col c+10
|
317
|
+
bind(:ENTER) { status_row.text "New button adds a new row below current " }
|
318
|
+
end
|
319
|
+
b_newrow.command { @new_act.call }
|
320
|
+
=end
|
321
|
+
## We use Action to create a button: to test out ampersand with MI and Button
|
322
|
+
new_act = @new_act
|
323
|
+
# using ampersand to set mnemonic
|
324
|
+
b_sort = Button.new @form do
|
325
|
+
text "&Sort"
|
326
|
+
row buttrow
|
327
|
+
col c+25
|
328
|
+
#bind(:ENTER) { status_row.text "Deletes focussed row" }
|
329
|
+
help_text "Sort focussed row"
|
330
|
+
end
|
331
|
+
b_sort.command {
|
332
|
+
if @sorted_key == atable.focussed_col
|
333
|
+
@sort_dir = !@sort_dir
|
334
|
+
else
|
335
|
+
@sort_dir = true
|
336
|
+
end
|
337
|
+
@sorted_key = atable.focussed_col
|
338
|
+
|
339
|
+
$log.debug " SORT = #{categ.getvalue}, #{atable.focussed_col}, sort:#{@sort_dir}"
|
340
|
+
d = @todo.sort categ.getvalue, atable.focussed_col, @sort_dir
|
341
|
+
atable.table_model.data = d
|
342
|
+
}
|
343
|
+
=begin
|
344
|
+
b_change = Button.new @form do
|
345
|
+
text "&Lock"
|
346
|
+
row buttrow
|
347
|
+
col c+35
|
348
|
+
command {
|
349
|
+
r = atable.focussed_row
|
350
|
+
#c = sel_col.value
|
351
|
+
#$log.debug " Update gets #{field.getvalue.class}"
|
352
|
+
#atable.set_value_at(r, c, field.getvalue)
|
353
|
+
toggle = atable.column(atable.focussed_col()).editable
|
354
|
+
if toggle.nil? or toggle==true
|
355
|
+
toggle = false
|
356
|
+
text "Un&lock"
|
357
|
+
else
|
358
|
+
toggle = true
|
359
|
+
text "&Lock "
|
360
|
+
end
|
361
|
+
#eventlabel.text "Set column #{atable.focussed_col()} editable to #{toggle}"
|
362
|
+
atable.column(atable.focussed_col()).editable toggle
|
363
|
+
alert("Set column #{atable.focussed_col()} editable to #{toggle}")
|
364
|
+
}
|
365
|
+
help_text "Toggles editable state of current column "
|
366
|
+
end
|
367
|
+
=end
|
368
|
+
#buttons = [b_save, b_newrow, b_delrow, b_move ]
|
369
|
+
#Button.button_layout buttons, buttrow
|
370
|
+
@klp = RubyCurses::KeyLabelPrinter.new @form, get_key_labels
|
371
|
+
@klp.set_key_labels get_key_labels_table, :table
|
372
|
+
atable.bind(:ENTER){ @klp.mode :table ;
|
373
|
+
}
|
374
|
+
atable.bind(:LEAVE){@klp.mode :normal;
|
375
|
+
}
|
376
|
+
|
377
|
+
|
378
|
+
@form.repaint
|
379
|
+
@window.wrefresh
|
380
|
+
Ncurses::Panel.update_panels
|
381
|
+
begin
|
382
|
+
while((ch = @window.getchar()) != ?\C-q )
|
383
|
+
colcount = tcm.column_count-1
|
384
|
+
s = keycode_tos ch
|
385
|
+
#status_row.text = "Pressed #{ch} , #{s}"
|
386
|
+
@form.handle_key(ch)
|
387
|
+
|
388
|
+
@form.repaint
|
389
|
+
@window.wrefresh
|
390
|
+
end
|
391
|
+
ensure
|
392
|
+
@window.destroy if !@window.nil?
|
393
|
+
end
|
394
|
+
end
|
395
|
+
def create_table_actions atable, todo, data, categ
|
396
|
+
#@new_act = Action.new("New Row", "mnemonic"=>"N") {
|
397
|
+
@new_act = Action.new("&New Row") {
|
398
|
+
cc = atable.get_table_column_model.column_count
|
399
|
+
if atable.row_count < 1
|
400
|
+
mod = nil
|
401
|
+
frow = 0
|
402
|
+
else
|
403
|
+
frow = atable.focussed_row
|
404
|
+
frow += 1
|
405
|
+
mod = atable.get_value_at(frow,0)
|
406
|
+
end
|
407
|
+
tmp = [mod, 5, "", "TODO", Time.now]
|
408
|
+
tm = atable.table_model
|
409
|
+
tm.insert frow, tmp
|
410
|
+
atable.set_focus_on frow
|
411
|
+
@status_row.text = "Added a row. Please press Save before changing Category."
|
412
|
+
alert("Added a row below current one. Use C-k to clear task.")
|
413
|
+
}
|
414
|
+
@new_act.accelerator "Alt-N"
|
415
|
+
@save_cmd = lambda {
|
416
|
+
todo.set_tasks_for_category categ, data
|
417
|
+
todo.dump
|
418
|
+
alert("Rewritten yaml file")
|
419
|
+
}
|
420
|
+
@del_cmd = lambda {
|
421
|
+
row = atable.focussed_row
|
422
|
+
if confirm("Do your really want to delete row #{row+1}?")== :YES
|
423
|
+
tm = atable.table_model
|
424
|
+
tm.delete_at row
|
425
|
+
else
|
426
|
+
@status_row.text = "Delete cancelled"
|
427
|
+
end
|
428
|
+
}
|
429
|
+
|
430
|
+
end
|
431
|
+
def make_popup table
|
432
|
+
require 'rbcurse/rpopupmenu'
|
433
|
+
tablemenu = RubyCurses::PopupMenu.new "Table"
|
434
|
+
#tablemenu.add(item = RubyCurses::MenuItem.new("Open",'O'))
|
435
|
+
tablemenu.add(item = RubyCurses::MenuItem.new("&Open"))
|
436
|
+
|
437
|
+
tablemenu.insert_separator 1
|
438
|
+
#tablemenu.add(RubyCurses::MenuItem.new "New",'N')
|
439
|
+
tablemenu.add(@new_act)
|
440
|
+
tablemenu.add(item = RubyCurses::MenuItem.new("&Save"))
|
441
|
+
item.command() { @save_cmd.call }
|
442
|
+
|
443
|
+
item=RubyCurses::MenuItem.new "Select"
|
444
|
+
item.accelerator = "Ctrl-X"
|
445
|
+
item.command() { table.toggle_row_selection() }
|
446
|
+
#item.enabled = false
|
447
|
+
tablemenu.add(item)
|
448
|
+
|
449
|
+
item=RubyCurses::MenuItem.new "Clr Selection"
|
450
|
+
item.accelerator = "Alt-e"
|
451
|
+
item.command() { table.clear_selection() }
|
452
|
+
item.enabled = table.selected_row_count > 0 ? true : false
|
453
|
+
tablemenu.add(item)
|
454
|
+
|
455
|
+
item=RubyCurses::MenuItem.new "Delete"
|
456
|
+
item.accelerator = "Alt-D"
|
457
|
+
item.command() { @del_cmd.call }
|
458
|
+
tablemenu.add(item)
|
459
|
+
|
460
|
+
gotomenu = RubyCurses::Menu.new "&Goto"
|
461
|
+
|
462
|
+
item = RubyCurses::MenuItem.new "Top"
|
463
|
+
item.accelerator = "Alt-0"
|
464
|
+
item.command() { table.goto_top }
|
465
|
+
gotomenu.add(item)
|
466
|
+
|
467
|
+
item = RubyCurses::MenuItem.new "Bottom"
|
468
|
+
item.accelerator = "Alt-9"
|
469
|
+
item.command() { table.goto_bottom }
|
470
|
+
gotomenu.add(item)
|
471
|
+
|
472
|
+
item = RubyCurses::MenuItem.new "Next Page"
|
473
|
+
item.accelerator = "Ctrl-n"
|
474
|
+
item.command() { table.scroll_forward }
|
475
|
+
gotomenu.add(item)
|
476
|
+
|
477
|
+
item = RubyCurses::MenuItem.new "Prev Page"
|
478
|
+
item.accelerator = "Ctrl-p"
|
479
|
+
item.command() { table.scroll_backward }
|
480
|
+
gotomenu.add(item)
|
481
|
+
|
482
|
+
tablemenu.add(gotomenu)
|
483
|
+
|
484
|
+
|
485
|
+
tablemenu.show @atable, 0,1
|
486
|
+
end
|
487
|
+
end
|
488
|
+
if $0 == __FILE__
|
489
|
+
include RubyCurses
|
490
|
+
include RubyCurses::Utils
|
491
|
+
|
492
|
+
begin
|
493
|
+
# Initialize curses
|
494
|
+
VER::start_ncurses # this is initializing colors via ColorMap.setup
|
495
|
+
$log = Logger.new("view.log")
|
496
|
+
$log.level = Logger::DEBUG
|
497
|
+
|
498
|
+
colors = Ncurses.COLORS
|
499
|
+
|
500
|
+
catch(:close) do
|
501
|
+
t = TodoApp.new
|
502
|
+
t.run
|
503
|
+
end
|
504
|
+
rescue => ex
|
505
|
+
ensure
|
506
|
+
VER::stop_ncurses
|
507
|
+
p ex if ex
|
508
|
+
p(ex.backtrace.join("\n")) if ex
|
509
|
+
$log.debug( ex) if ex
|
510
|
+
$log.debug(ex.backtrace.join("\n")) if ex
|
511
|
+
end
|
512
|
+
end
|