rbcurse 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG +1570 -0
- data/History.txt +6 -0
- data/Manifest.txt +54 -0
- data/README.txt +304 -0
- data/Rakefile +28 -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/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/rbcurse.rb +7 -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 +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
|