rbcurse 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (55) hide show
  1. data/CHANGELOG +1570 -0
  2. data/History.txt +6 -0
  3. data/Manifest.txt +54 -0
  4. data/README.txt +304 -0
  5. data/Rakefile +28 -0
  6. data/examples/qdfilechooser.rb +68 -0
  7. data/examples/rfe.rb +853 -0
  8. data/examples/rfe_renderer.rb +69 -0
  9. data/examples/test1.rb +242 -0
  10. data/examples/test2.rb +498 -0
  11. data/examples/testcombo.rb +95 -0
  12. data/examples/testkeypress.rb +61 -0
  13. data/examples/testmenu.rb +105 -0
  14. data/examples/testtable.rb +266 -0
  15. data/examples/testtabp.rb +106 -0
  16. data/examples/testtodo.rb +532 -0
  17. data/examples/viewtodo.rb +512 -0
  18. data/lib/rbcurse/action.rb +31 -0
  19. data/lib/rbcurse/applicationheader.rb +57 -0
  20. data/lib/rbcurse/celleditor.rb +120 -0
  21. data/lib/rbcurse/checkboxcellrenderer.rb +69 -0
  22. data/lib/rbcurse/colormap.rb +133 -0
  23. data/lib/rbcurse/comboboxcellrenderer.rb +45 -0
  24. data/lib/rbcurse/defaultlistselectionmodel.rb +49 -0
  25. data/lib/rbcurse/keylabelprinter.rb +143 -0
  26. data/lib/rbcurse/listcellrenderer.rb +99 -0
  27. data/lib/rbcurse/listkeys.rb +33 -0
  28. data/lib/rbcurse/listscrollable.rb +216 -0
  29. data/lib/rbcurse/listselectable.rb +67 -0
  30. data/lib/rbcurse/mapper.rb +108 -0
  31. data/lib/rbcurse/orderedhash.rb +77 -0
  32. data/lib/rbcurse/rcombo.rb +243 -0
  33. data/lib/rbcurse/rdialogs.rb +183 -0
  34. data/lib/rbcurse/rform.rb +845 -0
  35. data/lib/rbcurse/rinputdataevent.rb +36 -0
  36. data/lib/rbcurse/rlistbox.rb +804 -0
  37. data/lib/rbcurse/rmenu.rb +666 -0
  38. data/lib/rbcurse/rmessagebox.rb +325 -0
  39. data/lib/rbcurse/rpopupmenu.rb +754 -0
  40. data/lib/rbcurse/rtabbedpane.rb +259 -0
  41. data/lib/rbcurse/rtable.rb +1296 -0
  42. data/lib/rbcurse/rtextarea.rb +673 -0
  43. data/lib/rbcurse/rtextview.rb +335 -0
  44. data/lib/rbcurse/rwidget.rb +1731 -0
  45. data/lib/rbcurse/scrollable.rb +301 -0
  46. data/lib/rbcurse/selectable.rb +94 -0
  47. data/lib/rbcurse/table/tablecellrenderer.rb +85 -0
  48. data/lib/rbcurse/table/tabledatecellrenderer.rb +102 -0
  49. data/lib/rbcurse.rb +7 -0
  50. data/lib/ver/keyboard.rb +150 -0
  51. data/lib/ver/keyboard2.rb +170 -0
  52. data/lib/ver/ncurses.rb +102 -0
  53. data/lib/ver/window.rb +369 -0
  54. data/test/test_rbcurse.rb +0 -0
  55. metadata +118 -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