rkumar-rbcurse 0.1.1 → 0.1.2
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 +40 -0
- data/History.txt +13 -0
- data/README.txt +13 -12
- data/examples/rfe.rb +150 -34
- data/examples/rfe_renderer.rb +6 -0
- data/examples/sqlc.rb +419 -0
- data/examples/testtable.rb +0 -4
- data/examples/testtabp.rb +2 -0
- data/examples/testtodo.rb +73 -23
- data/examples/todocsv.csv +28 -0
- data/lib/rbcurse.rb +1 -1
- data/lib/rbcurse/defaultlistselectionmodel.rb +14 -0
- data/lib/rbcurse/listcellrenderer.rb +7 -0
- data/lib/rbcurse/listkeys.rb +7 -4
- data/lib/rbcurse/listscrollable.rb +144 -7
- data/lib/rbcurse/listselectable.rb +23 -2
- data/lib/rbcurse/rlistbox.rb +69 -15
- data/lib/rbcurse/rmessagebox.rb +14 -5
- data/lib/rbcurse/rtabbedpane.rb +64 -2
- data/lib/rbcurse/rtable.rb +223 -18
- data/lib/rbcurse/rtextarea.rb +34 -2
- data/lib/rbcurse/rtextview.rb +27 -4
- data/lib/rbcurse/rwidget.rb +9 -3
- data/lib/rbcurse/table/tablecellrenderer.rb +1 -0
- metadata +4 -1
@@ -3,8 +3,13 @@
|
|
3
3
|
module RubyCurses
|
4
4
|
module ListSelectable
|
5
5
|
|
6
|
-
|
7
|
-
|
6
|
+
## modified on 2009-02-13 23:41 to return model if no param passed
|
7
|
+
def list_selection_model(*lsm)
|
8
|
+
if lsm.empty?
|
9
|
+
@list_selection_model
|
10
|
+
else
|
11
|
+
@list_selection_model = lsm[0]
|
12
|
+
end
|
8
13
|
#@list_selection_model.selection_mode = @selection_mode || :MULTIPLE
|
9
14
|
end
|
10
15
|
def create_default_list_selection_model
|
@@ -15,6 +20,7 @@ module RubyCurses
|
|
15
20
|
end
|
16
21
|
|
17
22
|
def add_row_selection_interval ix0, ix1
|
23
|
+
$log.debug " def add_row_selection_interval #{ix0}, ix1"
|
18
24
|
# if row_selection_allowed
|
19
25
|
@list_selection_model.add_selection_interval ix0, ix1
|
20
26
|
end
|
@@ -64,4 +70,19 @@ module RubyCurses
|
|
64
70
|
attr_accessor :row_selection_allowed
|
65
71
|
attr_accessor :column_selection_allowed
|
66
72
|
end
|
73
|
+
class ListSelectionEvent
|
74
|
+
attr_accessor :firstrow, :lastrow, :source, :type
|
75
|
+
def initialize firstrow, lastrow, source, type
|
76
|
+
@firstrow = firstrow
|
77
|
+
@lastrow = lastrow
|
78
|
+
@source = source
|
79
|
+
@type = type
|
80
|
+
end
|
81
|
+
def to_s
|
82
|
+
"#{@type.to_s}, firstrow: #{@firstrow}, lastrow: #{@lastrow}, source: #{@source}"
|
83
|
+
end
|
84
|
+
def inspect
|
85
|
+
to_s
|
86
|
+
end
|
87
|
+
end
|
67
88
|
end
|
data/lib/rbcurse/rlistbox.rb
CHANGED
@@ -44,6 +44,7 @@ module RubyCurses
|
|
44
44
|
include Enumerable
|
45
45
|
include RubyCurses::EventHandler
|
46
46
|
attr_accessor :selected_index
|
47
|
+
attr_reader :last_regex # should i really keep here as public or maintain in listbox
|
47
48
|
|
48
49
|
def initialize anarray
|
49
50
|
@list = anarray.dup
|
@@ -64,6 +65,7 @@ module RubyCurses
|
|
64
65
|
@list.index(obj)
|
65
66
|
end
|
66
67
|
def length ; @list.length; end
|
68
|
+
alias :size :length
|
67
69
|
|
68
70
|
def insert off0, *data
|
69
71
|
@list.insert off0, *data
|
@@ -112,7 +114,7 @@ module RubyCurses
|
|
112
114
|
@list.dup
|
113
115
|
end
|
114
116
|
def on_enter_row object
|
115
|
-
|
117
|
+
#$log.debug " XXX on_enter_row of list_data"
|
116
118
|
fire_handler :ENTER_ROW, object
|
117
119
|
end
|
118
120
|
# ##
|
@@ -143,10 +145,10 @@ module RubyCurses
|
|
143
145
|
return find_match @last_regex, start, @search_end_ix
|
144
146
|
end
|
145
147
|
##
|
146
|
-
# find backwards
|
148
|
+
# find backwards, list_data_model
|
147
149
|
# Using this to start a search or continue search
|
148
150
|
def find_prev regex=@last_regex, start = @search_found_ix
|
149
|
-
raise "No previous search" if @last_regex.nil?
|
151
|
+
raise "No previous search" if regex.nil? # @last_regex.nil?
|
150
152
|
$log.debug " find_prev #{@search_found_ix} : #{@current_index}"
|
151
153
|
start -= 1 unless start == 0
|
152
154
|
@last_regex = regex
|
@@ -427,6 +429,7 @@ module RubyCurses
|
|
427
429
|
select_default_values
|
428
430
|
# when the combo box has a certain row in focus, the popup should have the same row in focus
|
429
431
|
|
432
|
+
install_keys
|
430
433
|
init_vars
|
431
434
|
install_list_keys
|
432
435
|
|
@@ -531,7 +534,7 @@ module RubyCurses
|
|
531
534
|
h = scrollatrow()
|
532
535
|
rc = row_count
|
533
536
|
$log.debug " listbxo got ch #{ch}"
|
534
|
-
|
537
|
+
#$log.debug " when kps #{@KEY_PREV_SELECTION} "
|
535
538
|
case ch
|
536
539
|
when KEY_UP # show previous value
|
537
540
|
previous_row
|
@@ -565,14 +568,21 @@ module RubyCurses
|
|
565
568
|
@repaint_required = true
|
566
569
|
when 27, ?\C-c:
|
567
570
|
editing_canceled @current_index if @cell_editing_allowed
|
571
|
+
cancel_block # block
|
568
572
|
when @KEY_ASK_FIND_FORWARD
|
569
|
-
|
573
|
+
# ask_search_forward
|
570
574
|
when @KEY_ASK_FIND_BACKWARD
|
571
|
-
|
575
|
+
# ask_search_backward
|
572
576
|
when @KEY_FIND_NEXT
|
573
|
-
|
577
|
+
# find_next
|
574
578
|
when @KEY_FIND_PREV
|
575
|
-
|
579
|
+
# find_prev
|
580
|
+
when @KEY_ASK_FIND
|
581
|
+
ask_search
|
582
|
+
when @KEY_FIND_MORE
|
583
|
+
find_more
|
584
|
+
when @KEY_BLOCK_SELECTOR
|
585
|
+
mark_block #selection
|
576
586
|
else
|
577
587
|
# this has to be fixed, if compo does not handle key it has to continue into next part FIXME
|
578
588
|
ret = :UNHANDLED # changed on 2009-01-27 13:14 not going into unhandled, tab not released
|
@@ -606,8 +616,10 @@ module RubyCurses
|
|
606
616
|
set_focus_on(ix)
|
607
617
|
end
|
608
618
|
end
|
619
|
+
# gets string to search and calls data models find prev
|
609
620
|
def ask_search_backward
|
610
621
|
regex = get_string("Enter regex to search (backward)")
|
622
|
+
@last_regex = regex
|
611
623
|
ix = @list.find_prev regex, @current_index
|
612
624
|
if ix.nil?
|
613
625
|
alert("No matching data for: #{regex}")
|
@@ -615,7 +627,8 @@ module RubyCurses
|
|
615
627
|
set_focus_on(ix)
|
616
628
|
end
|
617
629
|
end
|
618
|
-
|
630
|
+
## listbox find_prev
|
631
|
+
def OLDfind_prev
|
619
632
|
ix = @list.find_prev
|
620
633
|
regex = @last_regex
|
621
634
|
if ix.nil?
|
@@ -627,7 +640,7 @@ module RubyCurses
|
|
627
640
|
end
|
628
641
|
end
|
629
642
|
# table find_next
|
630
|
-
def
|
643
|
+
def OLDfind_next
|
631
644
|
ix = @list.find_next
|
632
645
|
regex = @last_regex
|
633
646
|
if ix.nil?
|
@@ -639,12 +652,12 @@ module RubyCurses
|
|
639
652
|
def on_enter
|
640
653
|
on_enter_row @current_index
|
641
654
|
set_form_row # added 2009-01-11 23:41
|
642
|
-
|
643
|
-
@repaint_required
|
655
|
+
#$log.debug " ONE ENTER LIST #{@current_index}, #{@form.row}"
|
656
|
+
@repaint_required = true
|
644
657
|
fire_handler :ENTER, self
|
645
658
|
end
|
646
659
|
def on_enter_row arow
|
647
|
-
|
660
|
+
#$log.debug " Listbox #{self} ENTER_ROW with curr #{@current_index}. row: #{arow} H: #{@handler.keys}"
|
648
661
|
#fire_handler :ENTER_ROW, arow
|
649
662
|
fire_handler :ENTER_ROW, self
|
650
663
|
@list.on_enter_row self
|
@@ -668,7 +681,8 @@ module RubyCurses
|
|
668
681
|
col = c+@left_margin # @form.col
|
669
682
|
# unfortunately 2009-01-11 19:47 combo boxes editable allows changing value
|
670
683
|
editor.prepare_editor self, row, col, value
|
671
|
-
|
684
|
+
editor.component.curpos = 0 # reset it after search, if user scrols down
|
685
|
+
set_form_col 0 #@left_margin
|
672
686
|
|
673
687
|
# set original value so we can cancel
|
674
688
|
# set row and col,
|
@@ -676,7 +690,7 @@ module RubyCurses
|
|
676
690
|
end
|
677
691
|
def on_leave_row arow
|
678
692
|
#$log.debug " Listbox #{self} leave with (cr: #{@current_index}) #{arow}: list[row]:#{@list[arow]}"
|
679
|
-
|
693
|
+
#$log.debug " Listbox #{self} leave with (cr: #{@current_index}) #{arow}: "
|
680
694
|
#fire_handler :LEAVE_ROW, arow
|
681
695
|
fire_handler :LEAVE_ROW, self
|
682
696
|
editing_completed arow
|
@@ -797,7 +811,47 @@ module RubyCurses
|
|
797
811
|
end
|
798
812
|
@repaint_required = true
|
799
813
|
end
|
814
|
+
def set_form_col col=0
|
815
|
+
super col+@left_margin
|
816
|
+
end
|
817
|
+
# experimental selection of multiple rows via block
|
818
|
+
# specify a block start and then a block end
|
819
|
+
# usage: bind mark_selection to a key. It works as a toggle.
|
820
|
+
# C-c will cancel any selection that has begun.
|
821
|
+
# added on 2009-02-19 22:37
|
822
|
+
def mark_block #selection
|
823
|
+
if @inside_block
|
824
|
+
@inside_block = false
|
825
|
+
end_block #selection
|
826
|
+
else
|
827
|
+
@inside_block = true
|
828
|
+
start_block #selection
|
829
|
+
end
|
830
|
+
end
|
831
|
+
# added on 2009-02-19 22:37
|
832
|
+
def cancel_block
|
833
|
+
@first_index = @last_index = nil
|
834
|
+
@inside_block = false
|
835
|
+
end
|
836
|
+
# sets marker for start of block
|
837
|
+
# added on 2009-02-19 22:37
|
838
|
+
def start_block #selection
|
839
|
+
@first_index = @current_index
|
840
|
+
@last_index = nil
|
841
|
+
end
|
842
|
+
# sets marker for end of block
|
843
|
+
# added on 2009-02-19 22:37
|
844
|
+
def end_block #selection
|
845
|
+
@last_index = current_index
|
846
|
+
lower = [@first_index, @last_index].min
|
847
|
+
higher = [@first_index, @last_index].max
|
848
|
+
#lower.upto(higher) do |i| @list.toggle_row_selection i; end
|
849
|
+
add_row_selection_interval(lower, higher)
|
850
|
+
@repaint_required = true
|
851
|
+
end
|
852
|
+
|
800
853
|
|
854
|
+
# ADD HERE
|
801
855
|
end # class listb
|
802
856
|
|
803
857
|
|
data/lib/rbcurse/rmessagebox.rb
CHANGED
@@ -111,8 +111,14 @@ module RubyCurses
|
|
111
111
|
make_buttons ["&OK"]
|
112
112
|
when "ok_cancel" #, "input", "list", "field_list"
|
113
113
|
make_buttons %w[&OK &Cancel]
|
114
|
+
# experience 2009-02-22 12:52 trapping y and n - hopefully wont cause an edit problem
|
115
|
+
@form.bind_key(?o){ press(?\M-o) }
|
116
|
+
@form.bind_key(?c){ press(?\M-c) }
|
114
117
|
when "yes_no"
|
115
118
|
make_buttons %w[&Yes &No]
|
119
|
+
# experience 2009-02-22 12:52 trapping y and n - hopefully wont cause an edit problem
|
120
|
+
@form.bind_key(?y){ press(?\M-y) }
|
121
|
+
@form.bind_key(?n){ press(?\M-n) }
|
116
122
|
when "yes_no_cancel"
|
117
123
|
make_buttons ["&Yes", "&No", "&Cancel"]
|
118
124
|
when "custom"
|
@@ -170,7 +176,6 @@ module RubyCurses
|
|
170
176
|
return @selected_index
|
171
177
|
end
|
172
178
|
def press ch
|
173
|
-
#$log.debug "message box handle_keys : #{ch}" if ch != -1
|
174
179
|
case ch
|
175
180
|
when -1
|
176
181
|
return
|
@@ -183,12 +188,14 @@ module RubyCurses
|
|
183
188
|
if field.respond_to? :fire
|
184
189
|
field.fire
|
185
190
|
end
|
186
|
-
|
187
|
-
|
191
|
+
#$log.debug "popup ENTER : #{@selected_index} "
|
192
|
+
#$log.debug "popup ENTER : #{field.name}" if !field.nil?
|
188
193
|
@stop = true
|
189
194
|
return
|
190
195
|
when 9
|
191
196
|
@form.select_next_field
|
197
|
+
when 353
|
198
|
+
@form.select_prev_field
|
192
199
|
else
|
193
200
|
# fields must return unhandled else we will miss hotkeys.
|
194
201
|
# On messageboxes, often if no edit field, then O and C are hot.
|
@@ -234,7 +241,7 @@ module RubyCurses
|
|
234
241
|
# XXX this needs to go up and decide height of window
|
235
242
|
if @message_height.nil?
|
236
243
|
@message_height = (message.length/display_length)+1
|
237
|
-
$log.debug " print_message: mh:#{@message_height}"
|
244
|
+
$log.debug " print_message: mh:#{@message_height}, ml: #{message.length}"
|
238
245
|
end
|
239
246
|
@message_height ||= 1
|
240
247
|
width = @layout[:width]
|
@@ -251,6 +258,7 @@ module RubyCurses
|
|
251
258
|
@message_col = (width-message.length)/2
|
252
259
|
end
|
253
260
|
@message_row = row
|
261
|
+
# FIXME : wont print if newline at end of message !!!
|
254
262
|
#@window.printstring( row, @message_col , message, color=$reversecolor)
|
255
263
|
# 2008-12-30 19:45 experimenting with label so we can get justify and wrapping.
|
256
264
|
#@window.printstring( row, @message_col , message, color=$reversecolor)
|
@@ -264,6 +272,7 @@ module RubyCurses
|
|
264
272
|
@message_col ||= 2
|
265
273
|
r = @message_row + @message_height + 1
|
266
274
|
c = @message_col
|
275
|
+
disp_len = @layout[:width]-8
|
267
276
|
defaultvalue = @default_value || ""
|
268
277
|
input_config = @config["input_config"] || {}
|
269
278
|
case @type.to_s
|
@@ -272,7 +281,7 @@ module RubyCurses
|
|
272
281
|
name "input"
|
273
282
|
row r
|
274
283
|
col c
|
275
|
-
display_length
|
284
|
+
display_length disp_len
|
276
285
|
set_buffer defaultvalue
|
277
286
|
end
|
278
287
|
when "list"
|
data/lib/rbcurse/rtabbedpane.rb
CHANGED
@@ -74,6 +74,9 @@ module RubyCurses
|
|
74
74
|
include EventHandler
|
75
75
|
dsl_accessor :row, :col
|
76
76
|
dsl_accessor :height, :width
|
77
|
+
dsl_accessor :button_type # ok, ok_cancel, yes_no
|
78
|
+
dsl_accessor :buttons # used if type :custom
|
79
|
+
attr_reader :selected_index
|
77
80
|
def initialize win, aconfig={}, &block
|
78
81
|
@parent = win
|
79
82
|
@tabs ||= []
|
@@ -161,6 +164,7 @@ module RubyCurses
|
|
161
164
|
}
|
162
165
|
|
163
166
|
end
|
167
|
+
create_buttons
|
164
168
|
@form.repaint
|
165
169
|
end
|
166
170
|
def display_form form
|
@@ -183,7 +187,14 @@ module RubyCurses
|
|
183
187
|
return form
|
184
188
|
end
|
185
189
|
def handle_keys
|
186
|
-
|
190
|
+
begin
|
191
|
+
while (( ch=@window.getchar()) != 999)
|
192
|
+
if ch == ?\C-q
|
193
|
+
@selected_index = -1 # this signifies cancel by ?C-q
|
194
|
+
@stop = true
|
195
|
+
return
|
196
|
+
end
|
197
|
+
return if @stop
|
187
198
|
@current_form ||= @form
|
188
199
|
ret = @current_form.handle_key(ch)
|
189
200
|
case ret
|
@@ -220,15 +231,66 @@ module RubyCurses
|
|
220
231
|
@form.repaint
|
221
232
|
#return :UNHANDLED if ret == :UNHANDLED
|
222
233
|
end
|
234
|
+
return if @stop
|
223
235
|
@current_form.window.wrefresh
|
224
236
|
@window.refresh
|
225
237
|
end
|
226
|
-
|
238
|
+
ensure
|
239
|
+
destroy
|
240
|
+
end
|
227
241
|
end
|
228
242
|
def destroy
|
229
243
|
@window.destroy
|
230
244
|
@forms.each { |f| w = f.window; w.destroy unless w.nil? }
|
231
245
|
end
|
246
|
+
def create_buttons
|
247
|
+
case @button_type.to_s.downcase
|
248
|
+
when "ok"
|
249
|
+
make_buttons ["&OK"]
|
250
|
+
when "ok_cancel" #, "input", "list", "field_list"
|
251
|
+
make_buttons %w[&OK &Cancel]
|
252
|
+
when "yes_no"
|
253
|
+
make_buttons %w[&Yes &No]
|
254
|
+
when "yes_no_cancel"
|
255
|
+
make_buttons ["&Yes", "&No", "&Cancel"]
|
256
|
+
when "custom"
|
257
|
+
raise "Blank list of buttons passed to custom" if @buttons.nil? or @buttons.size == 0
|
258
|
+
make_buttons @buttons
|
259
|
+
else
|
260
|
+
$log.debug "No buttontype passed for creating tabbedpane. Using default (OK)"
|
261
|
+
make_buttons ["&OK"]
|
262
|
+
end
|
263
|
+
end
|
264
|
+
def make_buttons names
|
265
|
+
total = names.inject(0) {|total, item| total + item.length + 4}
|
266
|
+
bcol = center_column total
|
267
|
+
|
268
|
+
brow = @layout[:height]-2
|
269
|
+
button_ct=0
|
270
|
+
names.each_with_index do |bname, ix|
|
271
|
+
text = bname
|
272
|
+
#underline = @underlines[ix] if !@underlines.nil?
|
273
|
+
|
274
|
+
button = Button.new @form do
|
275
|
+
text text
|
276
|
+
name bname
|
277
|
+
row brow
|
278
|
+
col bcol
|
279
|
+
#underline underline
|
280
|
+
highlight_background $reversecolor
|
281
|
+
color $datacolor
|
282
|
+
bgcolor $datacolor
|
283
|
+
end
|
284
|
+
index = button_ct
|
285
|
+
button.command { |form| @selected_index = index; @stop = true; $log.debug "Pressed Button #{bname}";}
|
286
|
+
button_ct += 1
|
287
|
+
bcol += text.length+6
|
288
|
+
end
|
289
|
+
end
|
290
|
+
def center_column textlen
|
291
|
+
width = @layout[:width]
|
292
|
+
return (width-textlen)/2
|
293
|
+
end
|
232
294
|
|
233
295
|
##
|
234
296
|
# nested class tab
|
data/lib/rbcurse/rtable.rb
CHANGED
@@ -4,7 +4,7 @@
|
|
4
4
|
* Author: rkumar (arunachalesha)
|
5
5
|
|
6
6
|
|
7
|
-
TODO: NOTE:
|
7
|
+
TODO: NOTE:
|
8
8
|
A few higher level methods check for no data but lower level ones do not.
|
9
9
|
|
10
10
|
--------
|
@@ -78,7 +78,11 @@ module RubyCurses
|
|
78
78
|
@toprow = 0
|
79
79
|
@to_print_borders ||= 1
|
80
80
|
@show_grid ||= 1
|
81
|
+
@_first_column_print = 0 # intro for horiz scrolling 2009-02-14 16:20
|
82
|
+
@_last_column_print = 0 # 2009-02-16 23:57 so we don't tab further etc.
|
83
|
+
# table needs to know what columns are being printed.
|
81
84
|
@curpos = 0
|
85
|
+
@inter_column_spacing = 1
|
82
86
|
# @selected_color ||= 'yellow'
|
83
87
|
# @selected_bgcolor ||= 'black'
|
84
88
|
@table_changed = true
|
@@ -112,6 +116,7 @@ module RubyCurses
|
|
112
116
|
end
|
113
117
|
# added 2009-01-07 13:05 so new scrollable can use
|
114
118
|
def row_count
|
119
|
+
return 0 if @table_model.nil?
|
115
120
|
@table_model.row_count
|
116
121
|
end
|
117
122
|
# added 2009-01-07 13:05 so new scrollable can use
|
@@ -123,17 +128,24 @@ module RubyCurses
|
|
123
128
|
# Sets the data in models
|
124
129
|
# Should replace if these are created. TODO FIXME
|
125
130
|
def set_data data, colnames_array
|
131
|
+
# next 2 added in case set_data called again
|
132
|
+
@table_changed = true
|
133
|
+
@repaint_required = true
|
126
134
|
if data.is_a? Array
|
127
135
|
model = RubyCurses::DefaultTableModel.new data, colnames_array
|
128
136
|
table_model model
|
129
137
|
elsif data.is_a? RubyCurses::TableModel
|
130
138
|
table_model data
|
139
|
+
else
|
140
|
+
raise "set_data: don't know how to handle data: #{data.class.to_s}"
|
131
141
|
end
|
132
142
|
if colnames_array.is_a? Array
|
133
143
|
model = DefaultTableColumnModel.new colnames_array
|
134
144
|
table_column_model model
|
135
145
|
elsif colnames_array.is_a? RubyCurses::TableColumnModel
|
136
146
|
table_column_model colnames_array
|
147
|
+
else
|
148
|
+
raise "set_data: don't know how to handle column data: #{colnames_array.class.to_s}"
|
137
149
|
end
|
138
150
|
create_default_list_selection_model
|
139
151
|
create_table_header
|
@@ -164,8 +176,13 @@ module RubyCurses
|
|
164
176
|
@table_model.bind(:TABLE_MODEL_EVENT){|lde| table_data_changed(lde) }
|
165
177
|
end
|
166
178
|
end
|
167
|
-
|
168
|
-
|
179
|
+
# updated this so no param will return the tcm 2009-02-14 12:31
|
180
|
+
def table_column_model(*val)
|
181
|
+
if val.empty?
|
182
|
+
return @table_column_model
|
183
|
+
end
|
184
|
+
tcm = val[0]
|
185
|
+
raise "data error: table_column_model wrong class" if !tcm.is_a? RubyCurses::TableColumnModel
|
169
186
|
@table_column_model = tcm
|
170
187
|
@table_column_model.bind(:TABLE_COLUMN_MODEL_EVENT) {|e|
|
171
188
|
table_structure_changed e
|
@@ -175,8 +192,9 @@ module RubyCurses
|
|
175
192
|
#@table_header.column_model(tcm) unless @table_header.nil?
|
176
193
|
@table_header.table_column_model=(tcm) unless @table_header.nil?
|
177
194
|
end
|
178
|
-
#
|
195
|
+
# @deprecated, avoid usage
|
179
196
|
def get_table_column_model
|
197
|
+
$log.debug " DEPRECATED. Pls use table_column_model()"
|
180
198
|
@table_column_model
|
181
199
|
end
|
182
200
|
#
|
@@ -381,11 +399,16 @@ module RubyCurses
|
|
381
399
|
end
|
382
400
|
end
|
383
401
|
editor = get_default_cell_editor_for_class cls
|
402
|
+
#$log.debug "EDIT_CELL_AT:1 #{cls} #{editor.component.display_length} = #{@table_column_model.column(col).width}i maxlen #{editor.component.maxlen}"
|
384
403
|
editor.component.display_length = @table_column_model.column(col).width
|
385
|
-
|
404
|
+
# maxlen won't be nil ! This used to work earlier
|
405
|
+
#editor.component.maxlen = editor.component.display_length if editor.component.respond_to? :maxlen and editor.component.maxlen.nil? # 2009-01-18 00:59 XXX don't overwrite if user has set
|
406
|
+
if editor.component.respond_to? :maxlen
|
407
|
+
editor.component.maxlen = @table_column_model.column(col).edit_length || editor.component.display_length
|
408
|
+
end
|
386
409
|
#$log.debug "EDIT_CELL_AT: #{cls} #{editor.component.display_length} = #{@table_column_model.column(col).width}i maxlen #{editor.component.maxlen}"
|
387
410
|
end
|
388
|
-
|
411
|
+
#$log.debug " got an EDITOR #{editor} :: #{editor.component} "
|
389
412
|
# by now we should have something to edit with. We just need to prepare the widgey.
|
390
413
|
prepare_editor editor, row, col, value
|
391
414
|
|
@@ -395,6 +418,14 @@ module RubyCurses
|
|
395
418
|
row = r + (row - @toprow) +1 # @form.row , 1 added for header row!
|
396
419
|
col = c+get_column_offset()
|
397
420
|
editor.prepare_editor self, row, col, value
|
421
|
+
# added on 2009-02-16 23:49
|
422
|
+
# if data is longer than can be displayed then update editors disp len too
|
423
|
+
if (col+editor.component.display_length)>= @col+@width
|
424
|
+
editor.component.display_length = @width-1-col
|
425
|
+
$log.debug "DDDXXX #{editor.component.display_length} = @width-1-col"
|
426
|
+
else
|
427
|
+
$log.debug "EEE if (#{col+editor.component.display_length})> #{@col+@width}"
|
428
|
+
end
|
398
429
|
@cell_editor = editor
|
399
430
|
@repaint_required = true
|
400
431
|
set_form_col
|
@@ -452,6 +483,7 @@ module RubyCurses
|
|
452
483
|
# key handling
|
453
484
|
# make separate methods so callable programmatically
|
454
485
|
def handle_key(ch)
|
486
|
+
return :UNHANDLED if @table_model.nil?
|
455
487
|
@current_index ||= 0
|
456
488
|
@toprow ||= 0
|
457
489
|
h = scrollatrow()
|
@@ -494,6 +526,12 @@ module RubyCurses
|
|
494
526
|
when @KEY_GOTO_BOTTOM
|
495
527
|
editing_stopped if @is_editing # 2009-01-16 16:06
|
496
528
|
goto_bottom
|
529
|
+
when @KEY_SCROLL_RIGHT
|
530
|
+
editing_stopped if @is_editing # dts 2009-02-17 00:35
|
531
|
+
scroll_right
|
532
|
+
when @KEY_SCROLL_LEFT
|
533
|
+
editing_stopped if @is_editing # dts 2009-02-17 00:35
|
534
|
+
scroll_left
|
497
535
|
else
|
498
536
|
# there could be a case of editing here too!
|
499
537
|
ret = process_key ch, self
|
@@ -565,14 +603,16 @@ module RubyCurses
|
|
565
603
|
end
|
566
604
|
def next_column
|
567
605
|
v = @current_column+1
|
568
|
-
if v < @table_column_model.column_count
|
606
|
+
if v < @table_column_model.column_count and v <= @_last_column_print
|
569
607
|
$log.debug " if v < #{@table_column_model.column_count} "
|
570
608
|
current_column v
|
571
609
|
else
|
572
|
-
if @current_index < row_count()-1
|
610
|
+
if @current_index < row_count()-1
|
573
611
|
$log.debug " GOING TO NEXT ROW FROM NEXT COL : #{@current_index} : #{row_count}"
|
574
612
|
@current_column = 0
|
613
|
+
@current_column = @_first_column_print # added 2009-02-17 00:01
|
575
614
|
next_row
|
615
|
+
set_form_col
|
576
616
|
else
|
577
617
|
return :UNHANDLED
|
578
618
|
end
|
@@ -581,11 +621,14 @@ module RubyCurses
|
|
581
621
|
def previous_column
|
582
622
|
v = @current_column-1
|
583
623
|
# returning unhandled so focus can go to prev field auto
|
584
|
-
if v <
|
624
|
+
if v < @_first_column_print and @current_index <= 0
|
585
625
|
return :UNHANDLED
|
586
626
|
end
|
587
|
-
if v <
|
627
|
+
if v < @_first_column_print and @current_index > 0
|
588
628
|
@current_column = @table_column_model.column_count-1
|
629
|
+
@current_column = @_last_column_print # added 2009-02-17 00:01
|
630
|
+
$log.debug " XXXXXX prev col #{@current_column}, las #{@_last_column_print}, fi: #{@_first_column_print}"
|
631
|
+
set_form_col
|
589
632
|
previous_row
|
590
633
|
else
|
591
634
|
current_column @current_column-1
|
@@ -693,7 +736,7 @@ module RubyCurses
|
|
693
736
|
super
|
694
737
|
set_form_row
|
695
738
|
set_form_col # 2009-01-17 01:35
|
696
|
-
on_enter_cell focussed_row(), focussed_col()
|
739
|
+
on_enter_cell focussed_row(), focussed_col() unless focussed_row().nil? or focussed_col().nil?
|
697
740
|
end
|
698
741
|
def on_leave
|
699
742
|
super
|
@@ -713,6 +756,7 @@ module RubyCurses
|
|
713
756
|
end
|
714
757
|
# protected
|
715
758
|
def get_column_offset columnid=@current_column
|
759
|
+
return 0 if @table_column_model.nil?
|
716
760
|
return @table_column_model.column(columnid).column_offset || 0
|
717
761
|
end
|
718
762
|
|
@@ -720,11 +764,16 @@ module RubyCurses
|
|
720
764
|
def repaint
|
721
765
|
return unless @repaint_required
|
722
766
|
print_border @form.window if @to_print_borders == 1 # do this once only, unless everything changes
|
767
|
+
return if @table_model.nil? # added 2009-02-17 12:45
|
768
|
+
@_first_column_print ||= 0
|
723
769
|
cc = @table_model.column_count
|
724
770
|
rc = @table_model.row_count
|
771
|
+
inter_column_padding = " " * @inter_column_spacing
|
772
|
+
@_last_column_print = cc-1
|
725
773
|
tcm = @table_column_model
|
726
774
|
tm = @table_model
|
727
775
|
tr = @toprow
|
776
|
+
_column_scrolling = false
|
728
777
|
acolor = get_color $datacolor
|
729
778
|
h = scrollatrow()
|
730
779
|
r,c = rowcol
|
@@ -734,18 +783,19 @@ module RubyCurses
|
|
734
783
|
# TCM should give modelindex of col which is used to fetch data from TM
|
735
784
|
r += 1 # save for header
|
736
785
|
0.upto(h) do |hh|
|
737
|
-
crow = tr+hh
|
786
|
+
crow = tr+hh # crow is the row
|
738
787
|
if crow < rc
|
739
|
-
offset = 0
|
788
|
+
offset = 0 # offset of column
|
740
789
|
# 0.upto(cc-1) do |colix|
|
790
|
+
focussed = @current_index == crow ? true : false
|
791
|
+
selected = is_row_selected crow
|
741
792
|
# we loop through column_model and fetch data based on model index
|
742
793
|
# FIXED better to call table.get_value_at since we may now
|
743
794
|
# introduce a view - 2009-01-18 18:21
|
744
795
|
tcm.each_with_index do |acolumn, colix|
|
796
|
+
next if colix < @_first_column_print
|
745
797
|
#acolumn = tcm.column(colix)
|
746
798
|
#model_index = acolumn.model_index
|
747
|
-
focussed = @current_index == crow ? true : false
|
748
|
-
selected = is_row_selected crow
|
749
799
|
content = get_value_at(crow, colix) # tables
|
750
800
|
#renderer = get_default_cell_renderer_for_class content.class.to_s
|
751
801
|
renderer = get_cell_renderer(crow, colix)
|
@@ -753,9 +803,33 @@ module RubyCurses
|
|
753
803
|
renderer = get_default_cell_renderer_for_class(content.class.to_s) if renderer.nil?
|
754
804
|
renderer.display_length acolumn.width unless acolumn.nil?
|
755
805
|
end
|
756
|
-
width = renderer.display_length +
|
806
|
+
width = renderer.display_length + @inter_column_spacing
|
757
807
|
#renderer.repaint @form.window, r+hh, c+(colix*11), content, focussed, selected
|
758
808
|
acolumn.column_offset = offset
|
809
|
+
# trying to ensure that no overprinting
|
810
|
+
# $log.debug " c+offset+width > @col+@width #{c+offset+width} > #{@col}+#{@width}"
|
811
|
+
# $log.debug " #{c}+#{offset}+#{width} > @col+@width #{c+offset+width} > #{@col}+#{@width}"
|
812
|
+
if c+offset+width > @col+@width
|
813
|
+
_column_scrolling = true
|
814
|
+
@_last_column_print = colix
|
815
|
+
#$log.debug " TABLE BREAKING SINCE "
|
816
|
+
#$log.debug " if c+offset+width > @col+@width #{c+offset+width} > #{@col}+#{@width}"
|
817
|
+
#$log.debug " if #{c}+#{offset}+#{width} > @col+@width #{c+offset+width} > #{@col}+#{@width}"
|
818
|
+
# experimental to print subset of last
|
819
|
+
space_left = (@width-3)-(offset) # 3 due to boundaries
|
820
|
+
space_left = 0 if space_left < 0
|
821
|
+
if content.length > space_left
|
822
|
+
clen = space_left
|
823
|
+
renderer.display_length clen
|
824
|
+
else
|
825
|
+
clen = -1
|
826
|
+
renderer.display_length space_left # content.length
|
827
|
+
end
|
828
|
+
# print the inter cell padding just in case things mess up while scrolling
|
829
|
+
@form.window.mvprintw r+hh, c+offset-@inter_column_spacing, inter_column_padding
|
830
|
+
renderer.repaint @form.window, r+hh, c+offset, crow, content[0..clen], focussed, selected
|
831
|
+
break
|
832
|
+
end
|
759
833
|
# added crow on 2009-02-11 22:46
|
760
834
|
renderer.repaint @form.window, r+hh, c+(offset), crow, content, focussed, selected
|
761
835
|
offset += width
|
@@ -768,12 +842,33 @@ module RubyCurses
|
|
768
842
|
if @is_editing
|
769
843
|
@cell_editor.component.repaint unless @cell_editor.nil? or @cell_editor.component.form.nil?
|
770
844
|
end
|
845
|
+
_print_more_columns_marker _column_scrolling
|
846
|
+
_print_more_data_marker(rc-1 > tr + h)
|
847
|
+
$log.debug " _print_more_data_marker(#{rc} >= #{tr} + #{h})"
|
771
848
|
@table_changed = false
|
772
849
|
@repaint_required = false
|
773
850
|
end
|
774
851
|
def print_border g
|
775
852
|
return unless @table_changed
|
776
853
|
g.print_border @row, @col, @height, @width, $datacolor
|
854
|
+
return if @table_model.nil?
|
855
|
+
rc = @table_model.row_count
|
856
|
+
h = scrollatrow()
|
857
|
+
_print_more_data_marker (rc>h)
|
858
|
+
end
|
859
|
+
# private
|
860
|
+
def _print_more_data_marker tf
|
861
|
+
marker = tf ? Ncurses::ACS_CKBOARD : Ncurses::ACS_VLINE
|
862
|
+
@form.window.mvwaddch @row+@height-1, @col+@width-1, marker
|
863
|
+
marker = @toprow > 0 ? Ncurses::ACS_CKBOARD : Ncurses::ACS_VLINE
|
864
|
+
@form.window.mvwaddch @row+1, @col+@width-1, marker
|
865
|
+
end
|
866
|
+
def _print_more_columns_marker tf
|
867
|
+
marker = tf ? Ncurses::ACS_CKBOARD : Ncurses::ACS_HLINE
|
868
|
+
@form.window.mvwaddch @row+@height, @col+@width-2, marker
|
869
|
+
# show if columns to left or not
|
870
|
+
marker = @_first_column_print > 0 ? Ncurses::ACS_CKBOARD : Ncurses::ACS_HLINE
|
871
|
+
@form.window.mvwaddch @row+@height, @col+@_first_column_print+1, marker
|
777
872
|
end
|
778
873
|
def print_header
|
779
874
|
return unless @table_changed
|
@@ -782,12 +877,29 @@ module RubyCurses
|
|
782
877
|
tcm = @table_column_model ## could have been overridden, should we use this at all
|
783
878
|
offset = 0
|
784
879
|
header_model.each_with_index do |tc, colix|
|
880
|
+
next if colix < @_first_column_print # added for scrolling rt and left 2009-02-14 17:49
|
785
881
|
acolumn = tcm.column colix
|
786
882
|
renderer = tc.cell_renderer
|
787
883
|
renderer = @table_header.default_renderer if renderer.nil?
|
788
884
|
renderer.display_length acolumn.width unless acolumn.nil?
|
789
885
|
width = renderer.display_length + 1
|
790
886
|
content = tc.header_value
|
887
|
+
if c+offset+width > @col+@width
|
888
|
+
#$log.debug " TABLE: experimental code to NOT print if chance of exceeding table width"
|
889
|
+
# 2009-02-14 14:24 now printing, but truncating data for last column
|
890
|
+
space_left = (@width-3)-(offset)
|
891
|
+
space_left = 0 if space_left < 0
|
892
|
+
if content.length > space_left
|
893
|
+
clen = space_left
|
894
|
+
renderer.display_length clen
|
895
|
+
else
|
896
|
+
clen = -1
|
897
|
+
renderer.display_length space_left
|
898
|
+
end
|
899
|
+
#$log.debug " TABLE BREAKING SINCE sl: #{space_left},#{crow},#{colix}: #{clen} "
|
900
|
+
renderer.repaint @form.window, r, c+(offset), 0, content[0..clen], false, false
|
901
|
+
break
|
902
|
+
end
|
791
903
|
renderer.repaint @form.window, r, c+(offset),0, content, false, false
|
792
904
|
offset += width
|
793
905
|
end
|
@@ -837,6 +949,97 @@ module RubyCurses
|
|
837
949
|
set_focus_on(ix)
|
838
950
|
end
|
839
951
|
end
|
952
|
+
def scroll_right
|
953
|
+
cc = @table_model.column_count
|
954
|
+
if @_first_column_print < cc-1
|
955
|
+
@_first_column_print += 1
|
956
|
+
@current_column = @_first_column_print
|
957
|
+
set_form_col # FIXME not looking too good till key press
|
958
|
+
@repaint_required = true
|
959
|
+
@table_changed = true # so columns are modified
|
960
|
+
end
|
961
|
+
end
|
962
|
+
def scroll_left
|
963
|
+
if @_first_column_print > 0
|
964
|
+
@_first_column_print -= 1
|
965
|
+
@current_column = @_first_column_print
|
966
|
+
set_form_col
|
967
|
+
@repaint_required = true
|
968
|
+
@table_changed = true
|
969
|
+
end
|
970
|
+
end
|
971
|
+
##
|
972
|
+
# Makes an estimate of columns sizes, returning a hash, and storing it as @column_widths
|
973
|
+
# based on checking first 20 rows of data.
|
974
|
+
# This does not try to fit all columns into table, but gives best width, so you
|
975
|
+
# can scroll right to see other columns.
|
976
|
+
# @params - columns is columns returned by database
|
977
|
+
# using the command: @columns, *rows = @db.execute2(command)
|
978
|
+
# @param - datatypes is an array returned by following command to DB
|
979
|
+
# @datatypes = @content[0].types
|
980
|
+
def estimate_column_widths columns, datatypes
|
981
|
+
tablewidth = @width-3
|
982
|
+
colwidths = {}
|
983
|
+
min_column_width = (tablewidth/columns.length) -1
|
984
|
+
$log.debug("min: #{min_column_width}, #{tablewidth}")
|
985
|
+
0.upto(20) do |rowix|
|
986
|
+
break if rowix >= row_count
|
987
|
+
#@content.each_with_index do |row, cix|
|
988
|
+
# break if cix >= 20
|
989
|
+
@table_column_model.each_with_index do |acolumn, ix|
|
990
|
+
col = get_value_at(rowix, ix)
|
991
|
+
colwidths[ix] ||= 0
|
992
|
+
colwidths[ix] = [colwidths[ix], col.length].max
|
993
|
+
end
|
994
|
+
end
|
995
|
+
total = 0
|
996
|
+
colwidths.each_pair do |k,v|
|
997
|
+
name = columns[k.to_i]
|
998
|
+
colwidths[name] = v
|
999
|
+
total += v
|
1000
|
+
end
|
1001
|
+
colwidths["__TOTAL__"] = total
|
1002
|
+
column_widths = colwidths
|
1003
|
+
@max_data_widths = column_widths.dup
|
1004
|
+
|
1005
|
+
columns.each_with_index do | col, i|
|
1006
|
+
if datatypes[i].match(/(real|int)/) != nil
|
1007
|
+
wid = column_widths[i]
|
1008
|
+
# cw = [column_widths[i], [8,min_column_width].min].max
|
1009
|
+
$log.debug("XXX #{wid}. #{columns[i].length}")
|
1010
|
+
cw = [wid, columns[i].length].max
|
1011
|
+
$log.debug("int #{col} #{column_widths[i]}, #{cw}")
|
1012
|
+
elsif datatypes[i].match(/(date)/) != nil
|
1013
|
+
cw = [column_widths[i], [12,min_column_width].min].max
|
1014
|
+
#cw = [12,min_column_width].min
|
1015
|
+
$log.debug("date #{col} #{column_widths[i]}, #{cw}")
|
1016
|
+
else
|
1017
|
+
cw = [column_widths[i], min_column_width].max
|
1018
|
+
if column_widths[i] <= col.length and col.length <= min_column_width
|
1019
|
+
cw = col.length
|
1020
|
+
end
|
1021
|
+
$log.debug("else #{col} #{column_widths[i]}, #{col.length} #{cw}")
|
1022
|
+
end
|
1023
|
+
column_widths[i] = cw
|
1024
|
+
total += cw
|
1025
|
+
end
|
1026
|
+
column_widths["__TOTAL__"] = total
|
1027
|
+
$log.debug("Estimated col widths: #{column_widths.inspect}")
|
1028
|
+
@column_widths = column_widths
|
1029
|
+
return column_widths
|
1030
|
+
end
|
1031
|
+
##
|
1032
|
+
# convenience method
|
1033
|
+
# sets column widths given an array of ints
|
1034
|
+
# You may get such an array from estimate_column_widths
|
1035
|
+
def set_column_widths cw
|
1036
|
+
tcm = @table_column_model
|
1037
|
+
tcm.each_with_index do |col, ix|
|
1038
|
+
col.width cw[ix]
|
1039
|
+
end
|
1040
|
+
table_structure_changed(nil)
|
1041
|
+
end
|
1042
|
+
# ADD METHODS HERE
|
840
1043
|
end # class Table
|
841
1044
|
|
842
1045
|
## TC
|
@@ -863,6 +1066,7 @@ module RubyCurses
|
|
863
1066
|
## added column_offset on 2009-01-12 19:01
|
864
1067
|
attr_accessor :column_offset # where we've place this guy. in case we need to position cursor
|
865
1068
|
attr_accessor :cell_editor
|
1069
|
+
dsl_accessor :edit_length # corresponds to maxlen, if not set, col width will be useda 2009-02-16 21:55
|
866
1070
|
|
867
1071
|
|
868
1072
|
def initialize model_index, identifier, header_value, width, config={}, &block
|
@@ -1161,8 +1365,8 @@ module RubyCurses
|
|
1161
1365
|
|
1162
1366
|
##
|
1163
1367
|
# LSM
|
1164
|
-
#
|
1165
|
-
class
|
1368
|
+
# XXX UNUSED
|
1369
|
+
class OLDDefaultListSelectionModel
|
1166
1370
|
include RubyCurses::EventHandler
|
1167
1371
|
attr_accessor :selection_mode
|
1168
1372
|
attr_reader :anchor_selection_index
|
@@ -1172,6 +1376,7 @@ module RubyCurses
|
|
1172
1376
|
@anchor_selection_index = -1
|
1173
1377
|
@lead_selection_index = -1
|
1174
1378
|
@selection_mode = :MULTIPLE
|
1379
|
+
$log.debug " OLD VERSION OF LIST SELECTION MODEL IN rtable.rb"
|
1175
1380
|
end
|
1176
1381
|
|
1177
1382
|
def clear_selection
|