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.
Files changed (52) hide show
  1. data/CHANGELOG +1577 -0
  2. data/README.txt +310 -0
  3. data/examples/qdfilechooser.rb +68 -0
  4. data/examples/rfe.rb +853 -0
  5. data/examples/rfe_renderer.rb +69 -0
  6. data/examples/test1.rb +242 -0
  7. data/examples/test2.rb +498 -0
  8. data/examples/testcombo.rb +95 -0
  9. data/examples/testkeypress.rb +61 -0
  10. data/examples/testmenu.rb +105 -0
  11. data/examples/testtable.rb +266 -0
  12. data/examples/testtabp.rb +106 -0
  13. data/examples/testtodo.rb +532 -0
  14. data/examples/viewtodo.rb +512 -0
  15. data/lib/rbcurse.rb +7 -0
  16. data/lib/rbcurse/action.rb +31 -0
  17. data/lib/rbcurse/applicationheader.rb +57 -0
  18. data/lib/rbcurse/celleditor.rb +120 -0
  19. data/lib/rbcurse/checkboxcellrenderer.rb +69 -0
  20. data/lib/rbcurse/colormap.rb +133 -0
  21. data/lib/rbcurse/comboboxcellrenderer.rb +45 -0
  22. data/lib/rbcurse/defaultlistselectionmodel.rb +49 -0
  23. data/lib/rbcurse/keylabelprinter.rb +143 -0
  24. data/lib/rbcurse/listcellrenderer.rb +99 -0
  25. data/lib/rbcurse/listkeys.rb +33 -0
  26. data/lib/rbcurse/listscrollable.rb +216 -0
  27. data/lib/rbcurse/listselectable.rb +67 -0
  28. data/lib/rbcurse/mapper.rb +108 -0
  29. data/lib/rbcurse/orderedhash.rb +77 -0
  30. data/lib/rbcurse/rcombo.rb +243 -0
  31. data/lib/rbcurse/rdialogs.rb +183 -0
  32. data/lib/rbcurse/rform.rb +845 -0
  33. data/lib/rbcurse/rinputdataevent.rb +36 -0
  34. data/lib/rbcurse/rlistbox.rb +804 -0
  35. data/lib/rbcurse/rmenu.rb +666 -0
  36. data/lib/rbcurse/rmessagebox.rb +325 -0
  37. data/lib/rbcurse/rpopupmenu.rb +754 -0
  38. data/lib/rbcurse/rtabbedpane.rb +259 -0
  39. data/lib/rbcurse/rtable.rb +1296 -0
  40. data/lib/rbcurse/rtextarea.rb +673 -0
  41. data/lib/rbcurse/rtextview.rb +335 -0
  42. data/lib/rbcurse/rwidget.rb +1731 -0
  43. data/lib/rbcurse/scrollable.rb +301 -0
  44. data/lib/rbcurse/selectable.rb +94 -0
  45. data/lib/rbcurse/table/tablecellrenderer.rb +85 -0
  46. data/lib/rbcurse/table/tabledatecellrenderer.rb +102 -0
  47. data/lib/ver/keyboard.rb +150 -0
  48. data/lib/ver/keyboard2.rb +170 -0
  49. data/lib/ver/ncurses.rb +102 -0
  50. data/lib/ver/window.rb +369 -0
  51. data/test/test_rbcurse.rb +0 -0
  52. metadata +117 -0
@@ -0,0 +1,673 @@
1
+ =begin
2
+ * Name: TextArea
3
+ * $Id$
4
+ * Description Editable text area
5
+ * Author: rkumar (arunachalesha)
6
+ TODO
7
+
8
+ moved from rform to this file on 2009-01-08 21:57
9
+ --------
10
+ * Date: 2008-11-14 23:43
11
+ * License:
12
+ Same as Ruby's License (http://www.ruby-lang.org/LICENSE.txt)
13
+
14
+ =end
15
+ require 'rubygems'
16
+ require 'ncurses'
17
+ require 'logger'
18
+ require 'rbcurse'
19
+ require 'rbcurse/listscrollable'
20
+ require 'rbcurse/rinputdataevent'
21
+
22
+ include Ncurses
23
+ include RubyCurses
24
+ module RubyCurses
25
+ extend self
26
+
27
+ ## a multiline text editing widget
28
+ # TODO - giving data to user - adding newlines, and withog adding.
29
+ # - respect newlines for incoming data
30
+ #
31
+ class TextArea < Widget
32
+ include ListScrollable
33
+ dsl_accessor :height
34
+ dsl_accessor :title
35
+ dsl_accessor :title_attrib # bold, reverse, normal
36
+ dsl_accessor :list # the array of data to be sent by user
37
+ dsl_accessor :maxlen # the array of data to be sent by user
38
+ attr_reader :toprow
39
+ #attr_reader :prow
40
+ #attr_reader :winrow
41
+ dsl_accessor :auto_scroll # boolean, keeps view at end as data is inserted.
42
+ dsl_accessor :print_footer
43
+ dsl_accessor :editable # allow editing
44
+ # attr_accessor :modified # boolean, value modified or not 2009-01-08 12:29 REM 2009-01-18 14:46
45
+
46
+ def initialize form, config={}, &block
47
+ @focusable = true
48
+ @editable = true
49
+ @left_margin = 1
50
+ @row = 0
51
+ @col = 0
52
+ @curpos = 0
53
+ # @show_focus = false
54
+ @list = []
55
+ super
56
+ @row_offset = @col_offset = 1
57
+ @orig_col = @col
58
+ # this does result in a blank line if we insert after creating. That's required at
59
+ # present if we wish to only insert
60
+ if @list.empty?
61
+ @list << "\r"
62
+ end
63
+ # @scrollatrow = @height-2
64
+ @content_rows = @list.length
65
+ @win = @form.window
66
+ # init_scrollable
67
+ print_borders
68
+ @maxlen ||= @width-2
69
+ init_vars
70
+ end
71
+ def init_vars
72
+ @repaint_required = true
73
+ @toprow = @current_index = @pcol = 0
74
+ end
75
+ def rowcol
76
+ # $log.debug "textarea rowcol : #{@row+@row_offset+@winrow}, #{@col+@col_offset}"
77
+ return @row+@row_offset, @col+@col_offset
78
+ end
79
+ ##
80
+ # this avoids wrapping. Better to use the <<.
81
+ def Oinsert off0, *data
82
+ @list.insert off0, *data
83
+ # fire_handler :CHANGE, self # 2008-12-09 14:56 NOT SURE
84
+ end
85
+ # private
86
+ def wrap_text(txt, col = @maxlen)
87
+ $log.debug "inside wrap text for :#{txt}"
88
+ txt.gsub(/(.{1,#{col}})( +|$\n?)|(.{1,#{col}})/,
89
+ "\\1\\3\n")
90
+ end
91
+ def remove_all
92
+ @list = []
93
+ end
94
+ ##
95
+ # trying to wrap and insert
96
+ def insert off0, data
97
+ if data.length > @maxlen
98
+ data = wrap_text data
99
+ # $log.debug "after wrap text done :#{data}"
100
+ data = data.split("\n")
101
+ data[-1] << "\r" #XXXX
102
+ else
103
+ data << "\r" if data[-1,1] != "\r" #XXXX
104
+ end
105
+ data.each do |row|
106
+ @list.insert off0, row
107
+ off0 += 1
108
+ end
109
+ #$log.debug " AFTER INSERT: #{@list}"
110
+ end
111
+ ##
112
+ # wraps line sent in if longer than maxlen
113
+ # Typically a line is sent in. We wrap and put a hard return at end.
114
+ def << data
115
+ if data.length > @maxlen
116
+ $log.debug "wrapped append for #{data}"
117
+ data = wrap_text data
118
+ $log.debug "after wrap text for :#{data}"
119
+ data = data.split("\n")
120
+ # 2009-01-01 22:24 the \n was needed so we would put a space at time of writing.
121
+ # we need a soft return so a space can be added when pushing down.
122
+ # commented off 2008-12-28 21:59
123
+ #data.each {|line| @list << line+"\n"}
124
+ data.each {|line| @list << line}
125
+ @list[-1] << "\r" #XXXX
126
+ else
127
+ $log.debug "normal append for #{data}"
128
+ data << "\r" if data[-1,1] != "\r" #XXXX
129
+ @list << data
130
+ end
131
+ goto_end if @auto_scroll # to test out.
132
+ self
133
+ end
134
+ def wrap_para line=@current_index
135
+ line ||= 0
136
+ l=[]
137
+ while true
138
+ if @list[line].nil? or @list[line]=="" or @list[line]==13 #"\r"
139
+ break
140
+ end
141
+ $log.debug "lastchar #{@list[line][-1]}, appending: #{@list[line]}]"
142
+ t = @list[line]
143
+ l << t.strip
144
+ @list.delete_at line
145
+ break if t[-1]==13 # "\r"
146
+ # line += 1
147
+ end
148
+ str=l.join(" ")
149
+ $log.debug " sending insert : #{str}."
150
+ insert line, str
151
+ end
152
+ ##
153
+ # private
154
+ def print_borders
155
+ window = @form.window
156
+ color = $datacolor
157
+ window.print_border @row, @col, @height, @width, color
158
+ print_title
159
+ =begin
160
+ hline = "+%s+" % [ "-"*(width-((1)*2)) ]
161
+ hline2 = "|%s|" % [ " "*(width-((1)*2)) ]
162
+ window.printstring( row=startrow, col=startcol, hline, color)
163
+ print_title
164
+ (startrow+1).upto(startrow+height-1) do |row|
165
+ window.printstring(row, col=startcol, hline2, color)
166
+ end
167
+ window.printstring(startrow+height, col=startcol, hline, color)
168
+ =end
169
+
170
+ end
171
+ # private
172
+ def print_title
173
+ @form.window.printstring( @row, @col+(@width-@title.length)/2, @title, $datacolor, @title_attrib) unless @title.nil?
174
+ end
175
+ # text_area print footer
176
+ def print_foot
177
+ @footer_attrib ||= Ncurses::A_REVERSE
178
+ footer = "R: #{@current_index+1}, C: #{@curpos}, #{@list.length} lines "
179
+ @form.window.printstring( @row + @height, @col+2, footer, $datacolor, @footer_attrib)
180
+ end
181
+ ### FOR scrollable ###
182
+ def get_content
183
+ @list
184
+ end
185
+ def get_window
186
+ @form.window
187
+ end
188
+ ### FOR scrollable ###
189
+ def repaint # textarea
190
+ return unless @repaint_required
191
+ paint
192
+ print_foot if @print_footer
193
+ end
194
+ def getvalue
195
+ @list
196
+ end
197
+ # textarea
198
+
199
+ def handle_key ch
200
+ @buffer = @list[@current_index]
201
+ if @buffer.nil? and @list.length == 0
202
+ @list << "\n" # changed space to newline so wrapping puts a line.
203
+ @buffer = @list[@current_index]
204
+ end
205
+ return if @buffer.nil?
206
+ $log.debug "TA: before: curpos #{@curpos} blen: #{@buffer.length}"
207
+ # on any line if the cursor is ahead of buffer length, ensure its on last position
208
+ # what if the buffer is somehow gt maxlen ??
209
+ if @curpos > @buffer.length
210
+ addcol(@buffer.length-@curpos)+1
211
+ @curpos = @buffer.length
212
+ end
213
+ $log.debug "TA: after : curpos #{@curpos} blen: #{@buffer.length}, w: #{@width} max #{@maxlen}"
214
+ #pre_key
215
+ case ch
216
+ when ?\C-n
217
+ scroll_forward
218
+ when ?\C-p
219
+ scroll_backward
220
+ when ?\C-[
221
+ goto_start #cursor_start of buffer
222
+ when ?\C-]
223
+ goto_end # cursor_end of buffer
224
+ when KEY_UP
225
+ #select_prev_row
226
+ ret = up
227
+ when KEY_DOWN
228
+ ret = down
229
+ when KEY_ENTER, 10, 13
230
+ insert_break
231
+ when KEY_LEFT
232
+ cursor_backward
233
+ when KEY_RIGHT
234
+ cursor_forward
235
+ when KEY_BACKSPACE, 127
236
+ if @editable # checking here means that i can programmatically bypass!!
237
+ delete_prev_char
238
+ #fire_handler :CHANGE, self # 2008-12-22 15:23
239
+ end
240
+ when 330, ?\C-d # delete char
241
+ if @editable
242
+ delete_curr_char
243
+ #fire_handler :CHANGE, self # 2008-12-22 15:23
244
+ end
245
+ when ?\C-k # delete till eol
246
+ if @editable
247
+ if @buffer == ""
248
+ delete_line
249
+ #fire_handler :CHANGE, self # 2008-12-22 15:23
250
+ else
251
+ delete_eol
252
+ #fire_handler :CHANGE, self # 2008-12-22 15:23
253
+ end
254
+ end
255
+ when ?\C-u
256
+ undo_delete
257
+ when ?\C-a
258
+ cursor_bol
259
+ when ?\C-e
260
+ cursor_eol
261
+ #set_form_col @buffer.length
262
+ else
263
+ #$log.debug(" textarea ch #{ch}")
264
+ ret = putc ch
265
+ return ret if ret == :UNHANDLED
266
+ end
267
+ #post_key
268
+ set_form_row
269
+ set_form_col # testing 2008-12-26 19:37
270
+ end
271
+ def undo_delete
272
+ # added 2008-11-27 12:43 paste delete buffer into insertion point
273
+ @buffer.insert @curpos, @delete_buffer unless @delete_buffer.nil?
274
+ set_modified
275
+ fire_handler :CHANGE, InputDataEvent.new(@curpos,@curpos+@delete_buffer.length, self, :INSERT, @current_index, @delete_buffer) # 2008-12-24 18:34
276
+ end
277
+ def insert_break
278
+ return -1 unless @editable
279
+ # insert a blank row and append rest of this line to cursor
280
+ $log.debug "ENTER PRESSED at #{@curpos}, on row #{@current_index}"
281
+ @delete_buffer = (delete_eol || "")
282
+ @list[@current_index] << "\r"
283
+ $log.debug "DELETE BUFFER #{@delete_buffer}"
284
+ @list.insert @current_index+1, @delete_buffer
285
+ @curpos = 0
286
+ down
287
+ @form.col = @orig_col + @col_offset
288
+ #addrowcol 1,0
289
+ @form.row = @row + 1 #+ @winrow
290
+ #fire_handler :CHANGE, self # 2008-12-09 14:56
291
+ fire_handler :CHANGE, InputDataEvent.new(@curpos,@curpos+@delete_buffer.length, self, :INSERT, @current_index, @delete_buffer) # 2008-12-24 18:34
292
+ end
293
+ # set cursor on correct column
294
+ def set_form_col col1=@curpos
295
+ @curpos = col1
296
+ cursor_bounds_check
297
+ @form.col = @orig_col + @col_offset + @curpos
298
+ $log.debug "sfc: #{@orig_col}, #{@col_offset}. #{@curpos}. "
299
+ end
300
+ def cursor_bounds_check
301
+ max = buffer_len()
302
+ @curpos = max if @curpos > max # check 2008-12-27 00:02
303
+ end
304
+ def buffer_len
305
+ @list[@current_index].nil? ? 0 : @list[@current_index].chomp().length
306
+ end
307
+ def do_current_row # :yields current row
308
+ yield @list[@current_index]
309
+ @buffer = @list[@current_index]
310
+ end
311
+ def delete_eol
312
+ return -1 unless @editable
313
+ pos = @curpos-1
314
+ @delete_buffer = @buffer[@curpos..-1]
315
+ # if pos is 0, pos-1 becomes -1, end of line!
316
+ @list[@current_index] = pos == -1 ? "" : @buffer[0..pos]
317
+ $log.debug "delete EOL :pos=#{pos}, #{@delete_buffer}: row: #{@list[@current_index]}:"
318
+ @buffer = @list[@current_index]
319
+ cursor_backward if @curpos > 0 # now cursor back goes up to prev line
320
+ #fire_handler :CHANGE, self # 2008-12-09 14:56
321
+ fire_handler :CHANGE, InputDataEvent.new(@curpos,@curpos+@delete_buffer.length, self, :DELETE, @current_index, @delete_buffer) # 2008-12-24 18:34
322
+ set_modified
323
+ return @delete_buffer
324
+ end
325
+ def cursor_forward num=1
326
+ $log.debug "next char cp #{@curpos}, #{@buffer.length}. wi: #{@width}"
327
+ #if @curpos < @width and @curpos < @maxlen-1 # else it will do out of box
328
+ if @curpos < buffer_len()
329
+ @curpos += 1
330
+ addcol 1
331
+ else # trying this out 2008-12-26 20:18
332
+ @curpos = 0
333
+ down
334
+ end
335
+ cursor_bounds_check
336
+ end
337
+ def addcol num
338
+ @form.addcol num
339
+ end
340
+ def addrowcol row,col
341
+ @form.addrowcol row, col
342
+ end
343
+ def cursor_backward
344
+ if @curpos > 0
345
+ @curpos -= 1
346
+ addcol -1
347
+ else # trying this out 2008-12-26 20:18
348
+ ret = up
349
+ cursor_eol if ret != -1
350
+ end
351
+ end
352
+ def delete_line line=@current_index
353
+ return -1 unless @editable
354
+ $log.debug "called delete line"
355
+ @delete_buffer = @list.delete_at line
356
+ @buffer = @list[@current_index]
357
+ if @buffer.nil?
358
+ up
359
+ @form.row = @row + 1 #+ @winrow
360
+ end
361
+ #fire_handler :CHANGE, self # 2008-12-09 14:56
362
+ fire_handler :CHANGE, InputDataEvent.new(@curpos,@curpos+@delete_buffer.length, self, :DELETE, @current_index, @delete_buffer) # 2008-12-24 18:34
363
+ set_modified
364
+ end
365
+ def delete_curr_char num=1
366
+ return -1 unless @editable
367
+ num.times do
368
+ delete_at
369
+ set_modified
370
+ end
371
+ end
372
+ def delete_prev_char num=1
373
+ return -1 if !@editable
374
+ num.times do
375
+ if @curpos <= 0
376
+ join_to_prev_line
377
+ return
378
+ end
379
+ @curpos -= 1 if @curpos > 0
380
+ delete_at
381
+ set_modified
382
+ addcol -1
383
+ end
384
+ end
385
+ # private
386
+ # when backspace pressed in position zero if the previous line is filled we may have to bring
387
+ # down the last word and join, rather than go up
388
+ def join_to_prev_line
389
+ return -1 unless @editable
390
+ return if @current_index == 0
391
+ oldcurpos = @curpos
392
+ oldprow = @current_index
393
+ prev = @list[@current_index-1].chomp
394
+ prevlen = prev.length
395
+ # 2008-12-26 21:37 delete previous line if nothing there. This moves entire buffer up.
396
+ if prevlen == 0
397
+ delete_line @current_index-1
398
+ up
399
+ return
400
+ end
401
+ space_left = @maxlen - prev.length
402
+ # BUG. carry full words up, or if no space then bring down last word of prev lien and join with first
403
+ carry_up = words_in_length @buffer, space_left #@buffer[0..space_left] # XXX
404
+ if carry_up.nil?
405
+ # carry down last word
406
+ prev_wd = remove_last_word @current_index-1
407
+ @buffer.insert 0, prev_wd
408
+ @curpos = prev_wd.length
409
+ $log.debug " carry up nil! prev_wd (#{prev_wd}) len:#{prev_wd.length}"
410
+ fire_handler :CHANGE, InputDataEvent.new(0,prev_wd.length, self, :INSERT, oldprow, prev_wd) # 2008-12-26 23:07
411
+ else
412
+ $log.debug " carrying up #{carry_up.length} #{carry_up}, space: #{space_left}"
413
+ @list[@current_index-1]=prev + carry_up
414
+ space_left2 = @buffer[(carry_up.length+1)..-1]
415
+ @list[@current_index]=space_left2 #if !space_left2.nil?
416
+ @list[@current_index] ||= ""
417
+ up
418
+ addrowcol -1,0
419
+ @curpos = prevlen
420
+ fire_handler :CHANGE, InputDataEvent.new(oldcurpos,carry_up.length, self, :DELETE, oldprow, carry_up) # 2008-12-24 18:34
421
+ fire_handler :CHANGE, InputDataEvent.new(prevlen,carry_up.length, self, :INSERT, oldprow-1, carry_up) # 2008-12-24 18:34
422
+ end
423
+ @form.col = @orig_col + @col_offset + @curpos
424
+
425
+ # $log.debug "carry up: nil" if carry_up.nil?
426
+ # $log.debug "listrow nil " if @list[@current_index].nil?
427
+ # $log.debug "carry up: #{carry_up} prow:#{@list[@current_index]}"
428
+ end
429
+ ##
430
+ # return as many words as fit into len for carrying up..
431
+ # actually there is a case of when the next char (len+1) is a white space or word boundary. XXX
432
+ def words_in_length buff, len
433
+ return nil if len == 0
434
+ str = buff[0..len]
435
+ ix = str.rindex(/\s/)
436
+ $log.debug " str #{str} len #{len} ix #{ix} , buff #{buff}~"
437
+ return nil if ix.nil?
438
+ ix = ix > 0 ? ix - 1 : ix
439
+ $log.debug " str[]:#{str[0..ix]}~ len #{len} ix #{ix} , buff #{buff}~"
440
+ return str[0..ix]
441
+ end
442
+ # push the last word from given line to next
443
+ # I have modified it to push all words that are exceeding maxlen.
444
+ # This was needed for if i push 10 chars to next line, and the last word is less then the line will
445
+ # exceed. So i must push as many words as exceed length.
446
+ def push_last_word lineno=@current_index
447
+ #lastspace = @buffer.rindex(" ")
448
+ #lastspace = @list[lineno].rindex(/ \w/)
449
+ line = @list[lineno]
450
+ line = @list[lineno][0..@maxlen+1] if line.length > @maxlen
451
+ lastspace = line.rindex(/ \w/)
452
+ $log.debug " PUSH:2 #{lastspace},#{line},"
453
+ if !lastspace.nil?
454
+ lastchars = @list[lineno][lastspace+1..-1]
455
+ @list[lineno] = @list[lineno][0..lastspace]
456
+ $log.debug "PUSH_LAST:ls:#{lastspace},lw:#{lastchars},lc:#{lastchars[-1]},:#{@list[lineno]}$"
457
+ if lastchars[-1,1] == "\r" or @list[lineno+1].nil?
458
+ # open a new line and keep the 10 at the end.
459
+ append_row lineno, lastchars
460
+ else
461
+ # check for soft tab \n - NO EVEN THIS LOGIC IS WRONG.
462
+ #if lastchars[-1,1] == "\n"
463
+ if lastchars[-1,1] != ' ' and @list[lineno+1][0,1] !=' '
464
+ #@list[lineno+1].insert 0, lastchars + ' '
465
+ insert_wrap lineno+1, 0, lastchars + ' '
466
+ else
467
+ #@list[lineno+1].insert 0, lastchars
468
+ insert_wrap lineno+1, 0, lastchars
469
+ end
470
+ end
471
+ return lastchars, lastspace
472
+ end
473
+ return nil
474
+ end
475
+ ##
476
+ # this attempts to recursively insert into a row, seeing that any stuff exceeding is pushed down further.
477
+ # Yes, it should check for a para end and insert. Currently it could add to next para.
478
+ def insert_wrap lineno, pos, lastchars
479
+ @list[lineno].insert pos, lastchars
480
+ len = @list[lineno].length
481
+ if len > @maxlen
482
+ push_last_word lineno #- sometime i may push down 10 chars but the last word is less
483
+ end
484
+ end
485
+ ##
486
+ # add one char. careful, i shoved a string in yesterday.
487
+ def putch char
488
+ @buffer ||= @list[@current_index]
489
+ return -1 if !@editable #or @buffer.length >= @maxlen
490
+ if @chars_allowed != nil
491
+ return if char.match(@chars_allowed).nil?
492
+ end
493
+ raise "putch expects only one char" if char.length != 1
494
+ oldcurpos = @curpos
495
+ $log.debug "putch : pr:#{@current_index}, cp:#{@curpos}, char:#{char}, lc:#{@buffer[-1]}, buf:(#{@buffer})"
496
+ @buffer.insert(@curpos, char)
497
+ @curpos += 1
498
+ $log.debug "putch INS: cp:#{@curpos}, max:#{@maxlen}, buf:(#{@buffer.length})"
499
+ if @curpos-1 > @maxlen or @buffer.length()-1 > @maxlen
500
+ lastchars, lastspace = push_last_word @current_index
501
+ #$log.debug "last sapce #{lastspace}, lastchars:#{lastchars},lc:#{lastchars[-1]}, #{@list[@current_index]} "
502
+ ## wrap on word XX If last char is 10 then insert line
503
+ @buffer = @list[@current_index]
504
+ if @curpos-1 > @maxlen or @curpos-1 > @buffer.length()-1
505
+ ret = down
506
+ # keep the cursor in the same position in the string that was pushed down.
507
+ @curpos = oldcurpos - lastspace #lastchars.length # 0
508
+ end
509
+ end
510
+ set_form_row
511
+ @buffer = @list[@current_index]
512
+ set_form_col
513
+ @modified = true
514
+ #fire_handler :CHANGE, self # 2008-12-09 14:56
515
+ fire_handler :CHANGE, InputDataEvent.new(oldcurpos,@curpos, self, :INSERT, @current_index, char) # 2008-12-24 18:34
516
+ @repaint_required = true
517
+ 0
518
+ end
519
+ def append_row lineno=@current_index, chars=""
520
+ $log.debug "append row sapce:#{chars}."
521
+ @list.insert lineno+1, chars
522
+ end
523
+ ##
524
+ # removes and returns last word in given line number, or nil if no whitespace
525
+ def remove_last_word lineno
526
+ @list[lineno].chomp!
527
+ line=@list[lineno]
528
+ lastspace = line.rindex(" ")
529
+ if !lastspace.nil?
530
+ lastchars = line[lastspace+1..-1]
531
+ @list[lineno].slice!(lastspace..-1)
532
+ $log.debug " remove_last: lastspace #{lastspace},#{lastchars},#{@list[lineno]}"
533
+ fire_handler :CHANGE, InputDataEvent.new(lastspace,lastchars.length, self, :DELETE, lineno, lastchars) # 2008-12-26 23:06
534
+ return lastchars
535
+ end
536
+ return nil
537
+ end
538
+
539
+ def putc c
540
+ if c >= 32 and c <= 126
541
+ ret = putch c.chr
542
+ if ret == 0
543
+ # addcol 1
544
+ set_modified
545
+ return 0
546
+ end
547
+ end
548
+ return :UNHANDLED
549
+ end
550
+ # DELETE func
551
+ def delete_at index=@curpos
552
+ return -1 if !@editable
553
+ $log.debug "dele : #{@current_index} #{@buffer} #{index}"
554
+ char = @buffer.slice!(@curpos,1) # changed added ,1 and take char for event
555
+ # if no newline at end of this then bring up prev character/s till maxlen
556
+ # NO WE DON'T DO THIS ANYLONGER 2008-12-26 21:09 lets see
557
+ =begin
558
+ if @buffer[-1,1]!="\r"
559
+ @buffer[-1]=" " if @buffer[-1,1]=="\n"
560
+ if !next_line.nil? and next_line.length > 0
561
+ move_chars_up
562
+ end
563
+ end
564
+ =end
565
+ #@modified = true 2008-12-22 15:31
566
+ set_modified true
567
+ #fire_handler :CHANGE, self # 2008-12-09 14:56
568
+ fire_handler :CHANGE, InputDataEvent.new(@curpos,@curpos, self, :DELETE, @current_index, char) # 2008-12-24 18:34
569
+ end
570
+ # move up one char from next row to current, used when deleting in a line
571
+ # should not be called if line ends in "\r"
572
+ def move_char_up
573
+ @list[@current_index] << @list[@current_index+1].slice!(0)
574
+ delete_line(@current_index+1) if next_line().length==0
575
+ end
576
+ # tries to move up as many as possible
577
+ # should not be called if line ends in "\r"
578
+ def move_chars_up
579
+ oldprow = @current_index
580
+ oldcurpos = @curpos
581
+ space_left = @maxlen - @buffer.length
582
+ can_move = [space_left, next_line.length].min
583
+ carry_up = @list[@current_index+1].slice!(0, can_move)
584
+ @list[@current_index] << carry_up
585
+ delete_line(@current_index+1) if next_line().length==0
586
+ fire_handler :CHANGE, InputDataEvent.new(oldcurpos,oldcurpos+can_move, self, :INSERT, oldprow, carry_up) # 2008-12-24 18:34
587
+ end
588
+ ## returns next line, does not move to it,
589
+ def next_line
590
+ @list[@current_index+1]
591
+ end
592
+ def current_line
593
+ @list[@current_index]
594
+ end
595
+ def do_relative_row num
596
+ yield @list[@current_index+num]
597
+ end
598
+ def set_modified tf=true
599
+ @modified = tf
600
+ @repaint_required = tf
601
+ @form.modified = true if tf
602
+ end
603
+ def cursor_eol
604
+ $log.error "ERROR !!! bufferlen gt maxlen #{@buffer.length}, #{@maxlen}" if @buffer.length > @maxlen
605
+ set_form_col current_line().chomp().length()-1
606
+ end
607
+ def cursor_bol
608
+ set_form_col 0
609
+ end
610
+ def to_s
611
+ l = getvalue
612
+ str = ""
613
+ old = " "
614
+ l.each_with_index do |line, i|
615
+ tmp = line.gsub("\n","")
616
+ tmp.gsub!("\r", "\n")
617
+ if old[-1,1] !~ /\s/ and tmp[0,1] !~ /\s/
618
+ str << " "
619
+ end
620
+ str << tmp
621
+ old = tmp
622
+ end
623
+ str
624
+ end
625
+ ## ---- for listscrollable ---- ##
626
+ def scrollatrow
627
+ @height-2
628
+ end
629
+ def row_count
630
+ @list.size
631
+ end
632
+ def paint
633
+ print_borders if @to_print_borders == 1 # do this once only, unless everything changes
634
+ rc = row_count
635
+ maxlen = @maxlen ||= @width-2
636
+ tm = get_content
637
+ tr = @toprow
638
+ acolor = get_color $datacolor
639
+ h = scrollatrow()
640
+ r,c = rowcol
641
+ $log.debug " TA:::: #{tr} , #{h}"
642
+ 0.upto(h) do |hh|
643
+ crow = tr+hh
644
+ if crow < rc
645
+ #focussed = @current_index == crow ? true : false
646
+ #selected = is_row_selected crow
647
+ content = tm[crow].chomp
648
+ content.gsub!(/\t/, ' ') # don't display tab
649
+ content.gsub!(/[^[:print:]]/, '') # don't display non print characters
650
+ if !content.nil?
651
+ if content.length > maxlen # only show maxlen
652
+ content = content[@pcol..@pcol+maxlen-1]
653
+ else
654
+ content = content[@pcol..-1]
655
+ end
656
+ end
657
+ #renderer = get_default_cell_renderer_for_class content.class.to_s
658
+ #renderer = cell_renderer()
659
+ #renderer.repaint @form.window, r+hh, c+(colix*11), content, focussed, selected
660
+ #renderer.repaint @form.window, r+hh, c, content, focussed, selected
661
+ @form.window.printstring r+hh, c, "%-*s" % [@width-2,content], acolor, @attr
662
+
663
+ else
664
+ # clear rows
665
+ @form.window.printstring r+hh, c, " " * (@width-2), acolor,@attr
666
+ end
667
+ end
668
+ @table_changed = false
669
+ @repaint_required = false
670
+ end
671
+ end # class textarea
672
+ ##
673
+ end # modul