rbcurse-core 0.0.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 (94) hide show
  1. data/README.md +69 -0
  2. data/VERSION +1 -0
  3. data/examples/abasiclist.rb +151 -0
  4. data/examples/alpmenu.rb +46 -0
  5. data/examples/app.sample +17 -0
  6. data/examples/atree.rb +100 -0
  7. data/examples/common/file.rb +45 -0
  8. data/examples/data/README.markdown +9 -0
  9. data/examples/data/brew.txt +38 -0
  10. data/examples/data/color.2 +37 -0
  11. data/examples/data/gemlist.txt +60 -0
  12. data/examples/data/lotr.txt +12 -0
  13. data/examples/data/ports.txt +136 -0
  14. data/examples/data/table.txt +37 -0
  15. data/examples/data/tasks.csv +88 -0
  16. data/examples/data/tasks.txt +27 -0
  17. data/examples/data/todo.txt +10 -0
  18. data/examples/data/todocsv.csv +28 -0
  19. data/examples/data/unix1.txt +21 -0
  20. data/examples/data/unix2.txt +11 -0
  21. data/examples/dbdemo.rb +487 -0
  22. data/examples/dirtree.rb +90 -0
  23. data/examples/newtabbedwindow.rb +100 -0
  24. data/examples/newtesttabp.rb +92 -0
  25. data/examples/tabular.rb +132 -0
  26. data/examples/tasks.rb +167 -0
  27. data/examples/term2.rb +83 -0
  28. data/examples/testkeypress.rb +72 -0
  29. data/examples/testlistbox.rb +158 -0
  30. data/examples/testmessagebox.rb +140 -0
  31. data/examples/testree.rb +106 -0
  32. data/examples/testwsshortcuts.rb +66 -0
  33. data/examples/testwsshortcuts2.rb +127 -0
  34. data/lib/rbcurse.rb +8 -0
  35. data/lib/rbcurse/core/docs/index.txt +73 -0
  36. data/lib/rbcurse/core/include/action.rb +40 -0
  37. data/lib/rbcurse/core/include/appmethods.rb +112 -0
  38. data/lib/rbcurse/core/include/bordertitle.rb +41 -0
  39. data/lib/rbcurse/core/include/chunk.rb +182 -0
  40. data/lib/rbcurse/core/include/io.rb +953 -0
  41. data/lib/rbcurse/core/include/listcellrenderer.rb +140 -0
  42. data/lib/rbcurse/core/include/listeditable.rb +317 -0
  43. data/lib/rbcurse/core/include/listscrollable.rb +590 -0
  44. data/lib/rbcurse/core/include/listselectable.rb +264 -0
  45. data/lib/rbcurse/core/include/multibuffer.rb +83 -0
  46. data/lib/rbcurse/core/include/orderedhash.rb +77 -0
  47. data/lib/rbcurse/core/include/ractionevent.rb +67 -0
  48. data/lib/rbcurse/core/include/rchangeevent.rb +27 -0
  49. data/lib/rbcurse/core/include/rhistory.rb +62 -0
  50. data/lib/rbcurse/core/include/rinputdataevent.rb +47 -0
  51. data/lib/rbcurse/core/include/vieditable.rb +170 -0
  52. data/lib/rbcurse/core/system/colormap.rb +163 -0
  53. data/lib/rbcurse/core/system/keyboard.rb +150 -0
  54. data/lib/rbcurse/core/system/keydefs.rb +30 -0
  55. data/lib/rbcurse/core/system/ncurses.rb +218 -0
  56. data/lib/rbcurse/core/system/panel.rb +162 -0
  57. data/lib/rbcurse/core/system/window.rb +901 -0
  58. data/lib/rbcurse/core/util/ansiparser.rb +117 -0
  59. data/lib/rbcurse/core/util/app.rb +1235 -0
  60. data/lib/rbcurse/core/util/basestack.rb +407 -0
  61. data/lib/rbcurse/core/util/bottomline.rb +1850 -0
  62. data/lib/rbcurse/core/util/colorparser.rb +71 -0
  63. data/lib/rbcurse/core/util/focusmanager.rb +31 -0
  64. data/lib/rbcurse/core/util/padreader.rb +189 -0
  65. data/lib/rbcurse/core/util/rcommandwindow.rb +587 -0
  66. data/lib/rbcurse/core/util/rdialogs.rb +619 -0
  67. data/lib/rbcurse/core/util/viewer.rb +149 -0
  68. data/lib/rbcurse/core/util/widgetshortcuts.rb +505 -0
  69. data/lib/rbcurse/core/widgets/applicationheader.rb +102 -0
  70. data/lib/rbcurse/core/widgets/box.rb +58 -0
  71. data/lib/rbcurse/core/widgets/divider.rb +310 -0
  72. data/lib/rbcurse/core/widgets/keylabelprinter.rb +178 -0
  73. data/lib/rbcurse/core/widgets/rcombo.rb +238 -0
  74. data/lib/rbcurse/core/widgets/rcontainer.rb +415 -0
  75. data/lib/rbcurse/core/widgets/rlink.rb +30 -0
  76. data/lib/rbcurse/core/widgets/rlist.rb +723 -0
  77. data/lib/rbcurse/core/widgets/rmenu.rb +939 -0
  78. data/lib/rbcurse/core/widgets/rmenulink.rb +22 -0
  79. data/lib/rbcurse/core/widgets/rmessagebox.rb +373 -0
  80. data/lib/rbcurse/core/widgets/rprogress.rb +118 -0
  81. data/lib/rbcurse/core/widgets/rtabbedpane.rb +615 -0
  82. data/lib/rbcurse/core/widgets/rtabbedwindow.rb +68 -0
  83. data/lib/rbcurse/core/widgets/rtextarea.rb +920 -0
  84. data/lib/rbcurse/core/widgets/rtextview.rb +780 -0
  85. data/lib/rbcurse/core/widgets/rtree.rb +787 -0
  86. data/lib/rbcurse/core/widgets/rwidget.rb +3040 -0
  87. data/lib/rbcurse/core/widgets/scrollbar.rb +143 -0
  88. data/lib/rbcurse/core/widgets/statusline.rb +94 -0
  89. data/lib/rbcurse/core/widgets/tabular.rb +264 -0
  90. data/lib/rbcurse/core/widgets/tabularwidget.rb +1211 -0
  91. data/lib/rbcurse/core/widgets/textpad.rb +516 -0
  92. data/lib/rbcurse/core/widgets/tree/treecellrenderer.rb +150 -0
  93. data/lib/rbcurse/core/widgets/tree/treemodel.rb +428 -0
  94. metadata +156 -0
@@ -0,0 +1,68 @@
1
+ =begin
2
+ * Name: newtabbedwindow.rb
3
+ * Description : This is a window that contains a tabbedpane (NewTabbedPane). This for situation
4
+ when you want to pop up a setup/configuration type of tabbed pane.
5
+ See examples/newtabbedwindow.rb for an example of usage, and test2.rb
6
+ which calls it from the menu (Options2 item).
7
+ In a short while, I will deprecate the existing complex TabbedPane and use this
8
+ in the lib/rbcurse dir.
9
+ * Author: rkumar (http://github.com/rkumar/rbcurse/)
10
+ * Date: 22.10.11 - 20:35
11
+ * License: Same as Ruby's License (http://www.ruby-lang.org/LICENSE.txt)
12
+ * Last update: Sat Oct 22 20:35:46 IST 2011
13
+
14
+ == CHANGES
15
+ == TODO
16
+ =end
17
+ require 'rbcurse'
18
+ require 'rbcurse/core/widgets/rtabbedpane'
19
+ require 'rbcurse/core/widgets/rcontainer'
20
+
21
+ include RubyCurses
22
+ class TabbedWindow
23
+ attr_reader :tabbed_pane
24
+ # The given block is passed to the TabbedPane
25
+ # The given dimensions are used to create the window.
26
+ # The TabbedPane is placed at 0,0 and fills the window.
27
+ def initialize config={}, &block
28
+
29
+ h = config.fetch(:height, 0)
30
+ w = config.fetch(:width, 0)
31
+ t = config.fetch(:row, 0)
32
+ l = config.fetch(:col, 0)
33
+ @window = VER::Window.new :height => h, :width => w, :top => t, :left => l
34
+ @form = Form.new @window
35
+ config[:row] = config[:col] = 0
36
+ @tabbed_pane = TabbedPane.new @form, config , &block
37
+ end
38
+ # returns button index
39
+ # Call this after instantiating the window
40
+ def run
41
+ @form.repaint
42
+ @window.wrefresh
43
+ return handle_keys
44
+ end
45
+ # returns button index
46
+ private
47
+ def handle_keys
48
+ buttonindex = catch(:close) do
49
+ while((ch = @window.getchar()) != FFI::NCurses::KEY_F10 )
50
+ break if ch == ?\C-q.getbyte(0)
51
+ begin
52
+ @form.handle_key(ch)
53
+ @window.wrefresh
54
+ rescue => err
55
+ $log.debug( err) if err
56
+ $log.debug(err.backtrace.join("\n")) if err
57
+ alert "Got an exception in NewTabbedWindow: #{err}. Check log"
58
+ $error_message.value = ""
59
+ ensure
60
+ end
61
+
62
+ end # while loop
63
+ end # close
64
+ $log.debug "XXX: CALLER GOT #{buttonindex} "
65
+ @window.destroy
66
+ return buttonindex
67
+ end
68
+ end
@@ -0,0 +1,920 @@
1
+ =begin
2
+ * Name: TextArea
3
+ * Description Editable text area
4
+ * Author: rkumar (arunachalesha)
5
+ 2009-12-26 14:43 buffered version of rtextarea.rb. See BUFFERED
6
+ * major change: 2010-02-12 13:34 simplifying the buffer stuff.
7
+ * see FIXME of textview for some common issues to look at.
8
+ * removed many edit functions to listeditable - 2010-03-12 10:16
9
+
10
+ Todo:
11
+ * shoud we store path, so a save can be done
12
+ --------
13
+ * Date: 2008-11-14 23:43
14
+ * License:
15
+ Same as Ruby's License (http://www.ruby-lang.org/LICENSE.txt)
16
+
17
+ =end
18
+ require 'logger'
19
+ require 'rbcurse'
20
+ require 'rbcurse/core/include/listscrollable'
21
+ require 'rbcurse/core/include/rinputdataevent'
22
+ require 'rbcurse/core/include/listeditable'
23
+
24
+ #include Ncurses # FFI 2011-09-8
25
+ include RubyCurses
26
+ module RubyCurses
27
+ extend self
28
+
29
+ ## a multiline text editing widget
30
+ # TODO - giving data to user - adding newlines, and withog adding.
31
+ # - respect newlines for incoming data
32
+ # we need a set_text method, passing nil or blank clears
33
+ # current way is not really good. remove_all sucks.
34
+ # TODO don't set maxlen if nil. compute it as a local in methods. Else splitpane will not
35
+ # work correctly.
36
+ class TextArea < Widget
37
+ include ListScrollable
38
+ # NOTE: common editing functions moved to listeditable
39
+ include ListEditable
40
+ dsl_accessor :title
41
+ dsl_accessor :title_attrib # bold, reverse, normal
42
+ dsl_accessor :footer_attrib # bold, reverse, normal added 2009-12-26 18:25 was this missing or delib
43
+ dsl_accessor :list # the array of data to be sent by user
44
+ dsl_accessor :maxlen # max display length of a row/line
45
+ attr_reader :toprow
46
+ dsl_accessor :auto_scroll # boolean, keeps view at end as data is inserted.
47
+ dsl_accessor :print_footer
48
+ dsl_accessor :editable # allow editing
49
+ dsl_accessor :suppress_borders # added 2010-02-12 12:21 values true or false
50
+ attr_accessor :overwrite_mode # boolean: insert or overwrite, default false.
51
+
52
+ def initialize form = nil, config={}, &block
53
+ @focusable = true
54
+ @editable = true
55
+ @row = 0
56
+ @col = 0
57
+ @curpos = 0
58
+ @list = []
59
+ @suppress_borders = false
60
+ @row_offset = @col_offset = 1 # for cursor display on first entry, so not positioned on border
61
+ @_events ||= []
62
+ @_events.push :CHANGE
63
+ super
64
+ @orig_col = @col
65
+ # this does result in a blank line if we insert after creating. That's required at
66
+ # present if we wish to only insert
67
+ if @list.empty?
68
+ # @list << "\r" # removed this on 2009-02-15 17:25 lets see how it goes
69
+ end
70
+ @content_rows = @list.length
71
+ @win = @graphic # 2009-12-26 14:54 BUFFERED replace form.window with graphic
72
+ # 2010-01-10 19:35 compute locally if not set
73
+ install_keys
74
+ init_vars
75
+ end
76
+ def init_vars
77
+ @repaint_required = true
78
+ @repaint_footer_required = true # 2010-01-23 22:41
79
+ @toprow = @current_index = @pcol = 0
80
+ @repaint_all=true
81
+ ## 2010-02-12 12:20 RFED16 taking care if no border requested
82
+ @row_offset = @col_offset = 0 if @suppress_borders == true
83
+ # added 2010-02-11 15:11 RFED16 so we don't need a form.
84
+ @win_left = 0
85
+ @win_top = 0
86
+ @longest_line = 0
87
+ # if borders used, reduce 2 from width else 0
88
+ @internal_width = 2
89
+ @internal_width = 2 if @suppress_borders
90
+ bind_key(?\M-w, :kill_ring_save)
91
+ bind_key(?\C-y, :yank)
92
+ bind_key(?\M-y, :yank_pop)
93
+ bind_key(?\M-\C-w, :append_next_kill)
94
+ map_keys
95
+ end
96
+ def rowcol
97
+ # $log.debug "textarea rowcol : #{@row+@row_offset+@winrow}, #{@col+@col_offset}"
98
+ return @row+@row_offset, @col+@col_offset
99
+ end
100
+ ##
101
+ # this avoids wrapping. Better to use the <<.
102
+ def Oinsert off0, *data
103
+ @list.insert off0, *data
104
+ # fire_handler :CHANGE, self # 2008-12-09 14:56 NOT SURE
105
+ end
106
+ # private
107
+ def wrap_text(txt, col = @maxlen)
108
+ col ||= @width - @internal_width
109
+ #$log.debug "inside wrap text for :#{txt}"
110
+ txt.gsub(/(.{1,#{col}})( +|$\n?)|(.{1,#{col}})/,
111
+ "\\1\\3\n")
112
+ end
113
+ ##
114
+ # trying to wrap and insert
115
+ def insert off0, data
116
+ _maxlen = @maxlen || @width - @internal_width
117
+ if data.length > _maxlen
118
+ data = wrap_text data
119
+ # $log.debug "after wrap text done :#{data}"
120
+ data = data.split("\n")
121
+ data[-1] << "\r" #XXXX
122
+ data.each do |row|
123
+ @list.insert off0, row
124
+ off0 += 1
125
+ end
126
+ else
127
+ data << "\r" if data[-1,1] != "\r" #XXXX
128
+ @list.insert off0, data
129
+ end
130
+ # expecting array !!
131
+ #data.each do |row|
132
+ #@list.insert off0, row
133
+ #off0 += 1
134
+ #end
135
+ #$log.debug " AFTER INSERT: #{@list}"
136
+ end
137
+ ##
138
+ # wraps line sent in if longer than _maxlen
139
+ # Typically a line is sent in. We wrap and put a hard return at end.
140
+ def << data
141
+ # if width if nil, either set it, or add this to a container that sets it before calling this method
142
+ _maxlen = @maxlen || @width - @internal_width
143
+ if data.length > _maxlen
144
+ #$log.debug "wrapped append for #{data}"
145
+ data = wrap_text data
146
+ #$log.debug "after wrap text for :#{data}"
147
+ data = data.split("\n")
148
+ # 2009-01-01 22:24 the \n was needed so we would put a space at time of writing.
149
+ # we need a soft return so a space can be added when pushing down.
150
+ # commented off 2008-12-28 21:59
151
+ #data.each {|line| @list << line+"\n"}
152
+ data.each {|line| @list << line}
153
+ @list[-1] << "\r" #XXXX
154
+ else
155
+ #$log.debug "normal append for #{data}"
156
+ data << "\r" if data[-1,1] != "\r" #XXXX
157
+ @list << data
158
+ end
159
+ set_modified # added 2009-03-07 18:29
160
+ goto_end if @auto_scroll
161
+ self
162
+ end
163
+ def wrap_para line=@current_index
164
+ line ||= 0
165
+ l=[]
166
+ while true
167
+ if @list[line].nil? or @list[line]=="" or @list[line]==13 #"\r"
168
+ break
169
+ end
170
+ #$log.debug "lastchar #{@list[line][-1]}, appending: #{@list[line]}]"
171
+ t = @list[line]
172
+ l << t.strip
173
+ @list.delete_at line
174
+ break if t[-1]==13 # "\r"
175
+ # line += 1
176
+ end
177
+ str=l.join(" ")
178
+ #$log.debug " sending insert : #{str}."
179
+ insert line, str
180
+ end
181
+ ##
182
+ # private
183
+ def print_borders
184
+ window = @graphic # 2009-12-26 14:54 BUFFERED
185
+ @color_pair = get_color($datacolor) # 2011-09-28 V1.3.1
186
+ bordercolor = @border_color || @color_pair
187
+ borderatt = @border_attrib || Ncurses::A_NORMAL
188
+ #color = $datacolor
189
+ #window.print_border @row, @col, @height, @width, color
190
+ window.print_border @row, @col, @height-1, @width, bordercolor, borderatt
191
+ print_title
192
+ =begin
193
+ hline = "+%s+" % [ "-"*(width-((1)*2)) ]
194
+ hline2 = "|%s|" % [ " "*(width-((1)*2)) ]
195
+ window.printstring( row=startrow, col=startcol, hline, color)
196
+ print_title
197
+ (startrow+1).upto(startrow+height-1) do |row|
198
+ window.printstring(row, col=startcol, hline2, color)
199
+ end
200
+ window.printstring(startrow+height, col=startcol, hline, color)
201
+ =end
202
+
203
+ end
204
+ # private
205
+ def print_title
206
+ # truncate title if longer than width
207
+ return unless @title
208
+ @color_pair ||= get_color($datacolor)
209
+ _title = @title
210
+ if @title.length > @width - 2
211
+ _title = @title[0..@width-2]
212
+ end
213
+ @graphic.printstring( @row, @col+(@width-_title.length)/2, _title, @color_pair, @title_attrib) unless @title.nil?
214
+ end
215
+ # text_area print footer
216
+ def print_foot
217
+ @footer_attrib ||= Ncurses::A_REVERSE
218
+ footer = "R: #{@current_index+1}, C: #{@curpos}, #{@list.length} lines "
219
+ #$log.debug " print_foot calling printstring with #{@row} + #{@height} -1, #{@col}+2"
220
+ # changed 2010-01-02 19:31 BUFFERED we were exceeding 1
221
+ #@graphic.printstring( @row + @height, @col+2, footer, $datacolor, @footer_attrib)
222
+ @graphic.printstring( @row + @height-1, @col+2, footer, @color_pair || $datacolor, @footer_attrib)
223
+ @repaint_footer_required = false
224
+ end
225
+ ### FOR scrollable ###
226
+ def get_content
227
+ @list
228
+ end
229
+ #
230
+ # sets content of textarea. I don't know why this was not existing all this while
231
+ # Name to be consistent with textview. Okay, this does not wrap the words, we assume
232
+ # its short enough. FIXME. Avoid using currently till i firm this.
233
+ # NOTE: does not wrap, and does not trigger events
234
+ # Added on 2011-10-10
235
+ # @since 1.4.0
236
+ # @param [String, Array] String is an existing filename, Array is content to be replaced
237
+ def set_content lines
238
+ case lines
239
+ when String
240
+ if File.exists? lines
241
+ lines = File.open(lines,"r").readlines
242
+ else
243
+ raise "set_content String param should be a filename"
244
+ end
245
+ when Array
246
+ else
247
+ raise "Don't know how to handle data in set_content: #{lines.class} "
248
+ end
249
+ @list.replace lines
250
+ @repaint_required = true
251
+ end
252
+ alias :text :set_content
253
+ def get_window
254
+ @graphic
255
+ end
256
+ ### FOR scrollable ###
257
+ def repaint # textarea
258
+ #return unless @repaint_required # 2010-02-12 19:08 TRYING - won't let footer print if only col move
259
+ paint if @repaint_required
260
+ print_foot if @print_footer && !@suppress_borders && (@repaint_footer_required || @repaint_required)
261
+ end
262
+ def getvalue
263
+ @list
264
+ end
265
+
266
+ def map_keys
267
+ return if @keys_mapped
268
+ bind_key(Ncurses::KEY_LEFT){ cursor_backward }
269
+ bind_key(Ncurses::KEY_RIGHT){ cursor_forward }
270
+ bind_key(Ncurses::KEY_UP){ ret = up; get_window.ungetch(KEY_BTAB) if ret == :NO_PREVIOUS_ROW }
271
+ # the next was irritating if user wanted to add a row ! 2011-10-10
272
+ #bind_key(Ncurses::KEY_DOWN){ ret = down ; get_window.ungetch(KEY_TAB) if ret == :NO_NEXT_ROW }
273
+ bind_key(Ncurses::KEY_DOWN){ ret = down ; }
274
+ bind_key(?\C-a){ cursor_bol }
275
+ bind_key(?\C-e){ cursor_eol }
276
+ bind_key(?\C-n) { scroll_forward }
277
+ bind_key(?\C-p) { scroll_backward }
278
+ bind_key(?\C-[) { goto_start }
279
+ bind_key(?\C-]) { goto_end }
280
+
281
+ bind_key(KEY_BACKSPACE){ delete_prev_char if @editable }
282
+ bind_key(KEY_BSPACE){ delete_prev_char if @editable}
283
+ bind_key(?\M-d, :delete_word)
284
+ bind_key(?\M-f, :forward_word)
285
+
286
+ #bind_key(127){ delete_prev_char }
287
+ bind_key(330){ delete_curr_char if @editable }
288
+ #bind_key(?\C-k){ delete_eol }
289
+ #bind_key(?\C-_){ undo_delete_eol }
290
+ #bind_key(27){ set_buffer @original_value }
291
+ @keys_mapped = true
292
+ end
293
+
294
+ # textarea
295
+ def handle_key ch
296
+ @current_key = ch # I need some funcs to know what key they were mapped to
297
+ @buffer = @list[@current_index]
298
+ if @buffer.nil? and @list.length == 0
299
+ ## 2009-10-04 22:39
300
+ # what this newline does is , if we use << to append, data is appended
301
+ # to second line
302
+ @list << "\n" # changed space to newline so wrapping puts a line.
303
+ @current_index = 0 ; ## added 2009-10-04 21:47
304
+ @buffer = @list[@current_index]
305
+ end
306
+ ## 2009-10-04 20:48 i think the next line was resulting in a hang if buffer nil
307
+ # in sqlc on pressing Clear.
308
+ # if buffer is nil and user wants to enter something -- added UNHANDLED
309
+ return :UNHANDLED if @buffer.nil?
310
+ #$log.debug "TA: before: curpos #{@curpos} blen: #{@buffer.length}"
311
+ # on any line if the cursor is ahead of buffer length, ensure its on last position
312
+ # what if the buffer is somehow gt maxlen ??
313
+ if @curpos > @buffer.length
314
+ addcol(@buffer.length-@curpos)+1
315
+ @curpos = @buffer.length
316
+ end
317
+ #$log.debug "TA: after : curpos #{@curpos} blen: #{@buffer.length}, w: #{@width} max #{@maxlen}"
318
+
319
+ case ch
320
+ when KEY_ENTER, 10, KEY_RETURN
321
+ insert_break
322
+ when Ncurses.KEY_BACKSPACE, Ncurses.KEY_BSPACE
323
+ if @editable # checking here means that i can programmatically bypass!!
324
+ delete_prev_char
325
+ end
326
+ when Ncurses.KEY_DELETE, ?\C-d.getbyte(0) # delete char
327
+ if @editable
328
+ delete_curr_char
329
+ end
330
+ when ?\C-k.getbyte(0) # delete till eol
331
+ # i'ved added curpos == 0 since emacs deletes a line if cursor is at 0
332
+ # Earlier behavior was based on alpine which leaves a blank line
333
+ if @editable
334
+ #if @buffer == ""
335
+ if @buffer.chomp == "" || @curpos == 0
336
+ delete_line
337
+ else
338
+ delete_eol
339
+ end
340
+ end
341
+ #when ?\C-u.getbyte(0)
342
+ ## since textareas are editable we use a control key to increase
343
+ ## multiplier. Series is 4 16 64
344
+ #@multiplier = (@multiplier == 0 ? 4 : @multiplier *= 4)
345
+ #return 0
346
+ when ?\C-_.getbyte(0) # changed from C-u so i can use C-u for multipliers
347
+ undo
348
+ when ?\C-r.getbyte(0) # redo if UndoHandler installed
349
+ text_redo # won't accept name redo
350
+ #when @KEY_ASK_FIND_FORWARD
351
+ # ask_search_forward
352
+ #when @KEY_ASK_FIND_BACKWARD
353
+ # ask_search_backward
354
+ when @KEY_ASK_FIND
355
+ ask_search
356
+ when @KEY_FIND_MORE
357
+ find_more
358
+ #when @KEY_FIND_NEXT
359
+ # find_next
360
+ #when @KEY_FIND_PREV
361
+ # find_prev
362
+ else
363
+ #$log.debug(" textarea ch #{ch}")
364
+ ret = putc ch
365
+ if ret == :UNHANDLED
366
+ # check for bindings, these cannot override above keys since placed at end
367
+ ret = process_key ch, self
368
+ #$log.debug "TA process_key #{ch} got ret #{ret} in #{@name} "
369
+ return :UNHANDLED if ret == :UNHANDLED
370
+ end
371
+ end
372
+ set_form_row
373
+ set_form_col # testing 2008-12-26 19:37
374
+ $multiplier = 0 # reset only if key handled
375
+ return 0
376
+ end
377
+ # this is broken, delete_buffer could be a line or a string or array of lines
378
+ def undo_delete
379
+ # added 2008-11-27 12:43 paste delete buffer into insertion point
380
+ return if @delete_buffer.nil?
381
+ $log.warn "undo_delete is broken! perhaps cannot be used . textarea 347 "
382
+ # FIXME - can be an array
383
+ case @delete_buffer
384
+ when Array
385
+ # we need to unroll array, and it could be lines not just a string
386
+ str = @delete_buffer.first
387
+ else
388
+ str = @delete_buffer
389
+ end
390
+ @buffer.insert @curpos, str
391
+ set_modified
392
+ fire_handler :CHANGE, InputDataEvent.new(@curpos,@curpos+@delete_buffer.length, self, :INSERT, @current_index, @delete_buffer) # 2008-12-24 18:34
393
+ end
394
+ # FIXME - fire event not correct, not undo'ing correctly, check row and also slash r append
395
+ def insert_break
396
+ return -1 unless @editable
397
+ # insert a blank row and append rest of this line to cursor
398
+ $log.debug "ENTER PRESSED at #{@curpos}, on row #{@current_index}"
399
+ @delete_buffer = (delete_eol || "")
400
+ @list[@current_index] << "\r"
401
+ $log.debug "DELETE BUFFER #{@delete_buffer}"
402
+ @list.insert @current_index+1, @delete_buffer
403
+ @curpos = 0
404
+ down
405
+ col = @orig_col + @col_offset
406
+ setrowcol @row+1, col
407
+ # FIXME maybe this should be insert line since line inserted, not just data, undo will delete it
408
+ fire_handler :CHANGE, InputDataEvent.new(@curpos,@curpos+@delete_buffer.length, self, :INSERT_LINE, @current_index, @delete_buffer) # 2008-12-24 18:34
409
+ end
410
+ # set cursor on correct column
411
+ def set_form_col col1=@curpos
412
+ @curpos = col1
413
+ @cols_panned ||= 0
414
+ cursor_bounds_check
415
+
416
+ ## added win_col on 2009-12-28 20:21 for embedded forms BUFFERED TRYING OUT
417
+ win_col = 0 # 2010-02-07 23:19 new cursor stuff
418
+ #col = win_col + @orig_col + @col_offset + @curpos
419
+ #col = win_col + @orig_col + @col_offset + @curpos + @cols_panned
420
+ # 2010-01-14 13:31 changed orig_col to col for embedded forms, splitpanes.
421
+ col = win_col + @col + @col_offset + @curpos + @cols_panned
422
+ $log.debug "sfc: wc:#{win_col} col:#{@col}, coff:#{@col_offset}. cp:#{@curpos} colsp:#{@cols_panned} . "
423
+ #@form.setrowcol @form.row, col # added 2009-12-29 18:50 BUFFERED
424
+ $log.debug " TA calling setformrow col nil, #{col} "
425
+ setrowcol nil, col # added 2009-12-29 18:50 BUFFERED
426
+ @repaint_footer_required = true
427
+ end
428
+ def cursor_bounds_check
429
+ max = buffer_len()
430
+ @curpos = max if @curpos > max # check 2008-12-27 00:02
431
+ end
432
+ def buffer_len
433
+ @list[@current_index].nil? ? 0 : @list[@current_index].chomp().length
434
+ end
435
+ def do_current_row # :yields current row
436
+ yield @list[@current_index]
437
+ @buffer = @list[@current_index]
438
+ end
439
+ ##
440
+ # FIXME : if cursor at end of last line then forward takes cursor to start
441
+ # of last line (same line), should stop there.
442
+ def cursor_forward num=1
443
+ #$log.debug "next char cp #{@curpos}, #{@buffer.length}. wi: #{@width}"
444
+ #$log.debug "next char cp ll and ci #{@list.length}, #{@current_index}"
445
+ #if @curpos < @width and @curpos < maxlen-1 # else it will do out of box
446
+ return if at_eol? and at_last_line?
447
+ repeatm {
448
+ if @curpos < buffer_len()
449
+ @curpos += 1
450
+ addcol 1
451
+ else # trying this out 2008-12-26 20:18
452
+ @curpos = 0
453
+ down 1 # if not then multipler will trigger there too
454
+ end
455
+ cursor_bounds_check
456
+ }
457
+ end
458
+ ## added 2009-10-04 22:13
459
+ # returns whether cursor is at end of line
460
+ def at_eol?
461
+ if @curpos+1== @list[@current_index].length
462
+ return true
463
+ end
464
+ return false
465
+ end
466
+ ## added 2009-10-04 22:13
467
+ # returns whether at last line (required so that forward does not go to start)
468
+ def at_last_line?
469
+ return true if @list.length == @current_index + 1
470
+ return false
471
+ end
472
+ # FIXME : these 2 only require the footer to be repainted not everything
473
+ # We should be able to manage that. We need a repaint_footer_required.
474
+ # Setting repaint_required really slows performance when one presses the right arrow key
475
+ # since a repaint is happenign repeatedly for each key.
476
+ def addcol num
477
+ # @repaint_required = true # added 2010-01-15 23:59, so that footer is updated, sucks!
478
+ @repaint_footer_required = true # 2010-01-23 22:41
479
+ my_win = @form || @parent_component.form # 2010-02-12 12:51
480
+ my_win.addcol num
481
+ end
482
+ def addrowcol row,col
483
+ #@repaint_required = true # added 2010-01-15 23:59
484
+ @repaint_footer_required = true # 2010-01-23 22:41
485
+ my_win = @form || @parent_component.form # 2010-02-12 12:51
486
+ my_win.addrowcol row, col
487
+ end
488
+ ## 2009-10-04 23:01 taken care that you can't go back at start of textarea
489
+ # it was going onto border
490
+ def cursor_backward
491
+ #$log.debug "back char cp ll and ci #{@list.length}, #{@current_index}"
492
+ #$log.debug "back char cb #{@curpos}, #{@buffer.length}. wi: #{@width}"
493
+ return if @curpos == 0 and @current_index == 0 # added 2009-10-04 23:02
494
+ repeatm {
495
+ if @curpos > 0
496
+ @curpos -= 1
497
+ addcol -1
498
+ else # trying this out 2008-12-26 20:18
499
+ ret = up
500
+ cursor_eol if ret != -1
501
+ end
502
+ }
503
+ end
504
+ # private
505
+ # when backspace pressed in position zero if the previous line is filled we may have to bring
506
+ # down the last word and join, rather than go up
507
+ # FIXME : make logic simple. Append entire line to above line. Then go to maxlen if not a space,
508
+ # reverse to find last space. Lop off all after space and replace this line with that balance.
509
+ # UNDO and REDO has to work in this case too. FIXME bare in mind handlers when doing this
510
+ def join_to_prev_line
511
+ return -1 unless @editable
512
+ return if @current_index == 0
513
+ oldcurpos = @curpos
514
+ oldprow = @current_index
515
+ prev = @list[@current_index-1].chomp
516
+ prevlen = prev.length
517
+ # 2008-12-26 21:37 delete previous line if nothing there. This moves entire buffer up.
518
+ if prevlen == 0
519
+ delete_line @current_index-1
520
+ up
521
+ return
522
+ end
523
+ _maxlen = @maxlen || @width - @internal_width
524
+ space_left = _maxlen - prevlen
525
+ # prev line is full exit
526
+ return if space_left == 0
527
+
528
+ # get last space, if none, return
529
+ blank_found = @buffer.rindex(' ', space_left)
530
+ return unless blank_found # no word in the space i can carry up.
531
+ # get string for carrying up
532
+ carry_up = @buffer[0..blank_found]
533
+ result = @list[@current_index-1].chomp! # this has to be undone too.
534
+ @list[@current_index-1] << carry_up
535
+ #$log.debug "carry up: #{carry_up} prevrow:#{@list[@current_index -1]}"
536
+ # remove from curr line
537
+ @list[@current_index].slice!(0..carry_up.length-1)
538
+ $log.debug "carry up: #{carry_up} currrow:#{@list[@current_index]}"
539
+ #@list[@current_index] ||= ""
540
+ up
541
+ addrowcol -1,0
542
+ @curpos = prevlen
543
+ # if result not nil, then we need that to be recorded FIXME
544
+ fire_handler :CHANGE, InputDataEvent.new(oldcurpos,oldcurpos+carry_up.length, self, :DELETE, oldprow, carry_up)
545
+ fire_handler :CHANGE, InputDataEvent.new(prevlen,prevlen+carry_up.length, self, :INSERT, oldprow-1, carry_up)
546
+
547
+ ## BUG. carry full words up, or if no space then bring down last word of prev lien and join with first
548
+ #carry_up = words_in_length @buffer, space_left #@buffer[0..space_left] # XXX
549
+ #if carry_up.nil?
550
+ ## carry down last word
551
+ #prev_wd = remove_last_word @current_index-1
552
+ ## 2010-01-14 18:26 check added else crashing if C-h pressed with no data in line
553
+ #if !prev_wd.nil?
554
+ #@buffer.insert 0, prev_wd
555
+ #@curpos = prev_wd.length
556
+ #$log.debug " carry up nil! prev_wd (#{prev_wd}) len:#{prev_wd.length}"
557
+ #fire_handler :CHANGE, InputDataEvent.new(0,prev_wd.length, self, :INSERT, oldprow, prev_wd) # 2008-12-26 23:07
558
+ #end
559
+ #else
560
+ #$log.debug " carrying up #{carry_up.length} #{carry_up}, space: #{space_left}"
561
+ #@list[@current_index-1]=prev + carry_up
562
+ #space_left2 = @buffer[(carry_up.length+1)..-1]
563
+ #@list[@current_index]=space_left2 #if !space_left2.nil?
564
+ #@list[@current_index] ||= ""
565
+ #up
566
+ #addrowcol -1,0
567
+ #@curpos = prevlen
568
+ #fire_handler :CHANGE, InputDataEvent.new(oldcurpos,carry_up.length, self, :DELETE, oldprow, carry_up) # 2008-12-24 18:34
569
+ #fire_handler :CHANGE, InputDataEvent.new(prevlen,carry_up.length, self, :INSERT, oldprow-1, carry_up) # 2008-12-24 18:34
570
+ #end
571
+ ## FIXME -- can;t have a naked for reference here.
572
+ ##@form.col = @orig_col + @col_offset + @curpos
573
+ col1 = @orig_col + @col_offset + @curpos
574
+ setrowcol nil, col1 # 2010-02-12 13:09 RFED16
575
+
576
+ # $log.debug "carry up: nil" if carry_up.nil?
577
+ # $log.debug "listrow nil " if @list[@current_index].nil?
578
+ # $log.debug "carry up: #{carry_up} prow:#{@list[@current_index]}"
579
+ end
580
+ # private
581
+ # when backspace pressed in position zero if the previous line is filled we may have to bring
582
+ # down the last word and join, rather than go up
583
+ # FIXME : make logic simple. Append entire line to above line. Then go to maxlen if not a space,
584
+ # reverse to find last space. Lop off all after space and replace this line with that balance.
585
+ # UNDO and REDO has to work in this case too. FIXME bare in mind handlers when doing this
586
+ def old_join_to_prev_line
587
+ return -1 unless @editable
588
+ return if @current_index == 0
589
+ oldcurpos = @curpos
590
+ oldprow = @current_index
591
+ prev = @list[@current_index-1].chomp
592
+ prevlen = prev.length
593
+ # 2008-12-26 21:37 delete previous line if nothing there. This moves entire buffer up.
594
+ if prevlen == 0
595
+ delete_line @current_index-1
596
+ up
597
+ return
598
+ end
599
+ _maxlen = @maxlen || @width - @internal_width
600
+ space_left = _maxlen - prev.length
601
+ # BUG. carry full words up, or if no space then bring down last word of prev lien and join with first
602
+ carry_up = words_in_length @buffer, space_left #@buffer[0..space_left] # XXX
603
+ if carry_up.nil?
604
+ # carry down last word
605
+ prev_wd = remove_last_word @current_index-1
606
+ # 2010-01-14 18:26 check added else crashing if C-h pressed with no data in line
607
+ if !prev_wd.nil?
608
+ @buffer.insert 0, prev_wd
609
+ @curpos = prev_wd.length
610
+ $log.debug " carry up nil! prev_wd (#{prev_wd}) len:#{prev_wd.length}"
611
+ fire_handler :CHANGE, InputDataEvent.new(0,prev_wd.length, self, :INSERT, oldprow, prev_wd) # 2008-12-26 23:07
612
+ end
613
+ else
614
+ $log.debug " carrying up #{carry_up.length} #{carry_up}, space: #{space_left}"
615
+ @list[@current_index-1]=prev + carry_up
616
+ space_left2 = @buffer[(carry_up.length+1)..-1]
617
+ @list[@current_index]=space_left2 #if !space_left2.nil?
618
+ @list[@current_index] ||= ""
619
+ up
620
+ addrowcol -1,0
621
+ @curpos = prevlen
622
+ fire_handler :CHANGE, InputDataEvent.new(oldcurpos,carry_up.length, self, :DELETE, oldprow, carry_up) # 2008-12-24 18:34
623
+ fire_handler :CHANGE, InputDataEvent.new(prevlen,carry_up.length, self, :INSERT, oldprow-1, carry_up) # 2008-12-24 18:34
624
+ end
625
+ # FIXME -- can;t have a naked for reference here.
626
+ #@form.col = @orig_col + @col_offset + @curpos
627
+ col1 = @orig_col + @col_offset + @curpos
628
+ setrowcol nil, col1 # 2010-02-12 13:09 RFED16
629
+
630
+ # $log.debug "carry up: nil" if carry_up.nil?
631
+ # $log.debug "listrow nil " if @list[@current_index].nil?
632
+ # $log.debug "carry up: #{carry_up} prow:#{@list[@current_index]}"
633
+ end
634
+ ##
635
+ # return as many words as fit into len for carrying up..
636
+ # actually there is a case of when the next char (len+1) is a white space or word boundary. XXX
637
+ def words_in_length buff, len
638
+ return nil if len == 0
639
+ str = buff[0..len]
640
+ ix = str.rindex(/\s/)
641
+ $log.debug " str #{str} len #{len} ix #{ix} , buff #{buff}~"
642
+ return nil if ix.nil?
643
+ ix = ix > 0 ? ix - 1 : ix
644
+ $log.debug " str[]:#{str[0..ix]}~ len #{len} ix #{ix} , buff #{buff}~"
645
+ return str[0..ix]
646
+ end
647
+ # push the last word from given line to next
648
+ # I have modified it to push all words that are exceeding maxlen.
649
+ # This was needed for if i push 10 chars to next line, and the last word is less then the line will
650
+ # exceed. So i must push as many words as exceed length.
651
+ # 2010-09-07 22:31 this must not return nil, or previous will crash. This happens if no space in line.
652
+ def push_last_word lineno=@current_index
653
+ _maxlen = @maxlen || @width - @internal_width
654
+ #lastspace = @buffer.rindex(" ")
655
+ #lastspace = @list[lineno].rindex(/ \w/)
656
+ line = @list[lineno]
657
+ line = @list[lineno][0.._maxlen+1] if line.length > _maxlen
658
+ lastspace = line.rindex(/ \w/)
659
+ $log.debug " PUSH:2 #{lastspace},#{line},"
660
+ # fix to ensure something returned 2010-09-07 22:40
661
+ lastspace = _maxlen-1 unless lastspace # added 2010-09-07 22:29 XXXX
662
+
663
+ if !lastspace.nil?
664
+ lastchars = @list[lineno][lastspace+1..-1]
665
+ @list[lineno] = @list[lineno][0..lastspace]
666
+ $log.debug "PUSH_LAST:ls:#{lastspace},lw:#{lastchars},lc:#{lastchars[-1]},:#{@list[lineno]}$"
667
+ if lastchars[-1,1] == "\r" or @list[lineno+1].nil?
668
+ # open a new line and keep the 10 at the end.
669
+ append_row lineno, lastchars
670
+ else
671
+ # check for soft tab \n - NO EVEN THIS LOGIC IS WRONG.
672
+ #if lastchars[-1,1] == "\n"
673
+ if lastchars[-1,1] != ' ' and @list[lineno+1][0,1] !=' '
674
+ #@list[lineno+1].insert 0, lastchars + ' '
675
+ insert_wrap lineno+1, 0, lastchars + ' '
676
+ else
677
+ #@list[lineno+1].insert 0, lastchars
678
+ insert_wrap lineno+1, 0, lastchars
679
+ end
680
+ end
681
+ return lastchars, lastspace
682
+ end
683
+ return nil
684
+ end
685
+ ##
686
+ # this attempts to recursively insert into a row, seeing that any stuff exceeding is pushed down further.
687
+ # Yes, it should check for a para end and insert. Currently it could add to next para.
688
+ def insert_wrap lineno, pos, lastchars
689
+ _maxlen = @maxlen || @width - @internal_width
690
+ @list[lineno].insert pos, lastchars
691
+ len = @list[lineno].length
692
+ if len > _maxlen
693
+ push_last_word lineno #- sometime i may push down 10 chars but the last word is less
694
+ end
695
+ end
696
+ ##
697
+ # add one char. careful, i shoved a string in yesterday.
698
+ def putch char
699
+ _maxlen = @maxlen || @width - @internal_width
700
+ @buffer ||= @list[@current_index]
701
+ return -1 if !@editable #or @buffer.length >= _maxlen
702
+ #if @chars_allowed != nil # remove useless functionality
703
+ #return if char.match(@chars_allowed).nil?
704
+ #end
705
+ raise "putch expects only one char" if char.length != 1
706
+ oldcurpos = @curpos
707
+ #$log.debug "putch : pr:#{@current_index}, cp:#{@curpos}, char:#{char}, lc:#{@buffer[-1]}, buf:(#{@buffer})"
708
+ if @overwrite_mode
709
+ @buffer[@curpos] = char
710
+ else
711
+ @buffer.insert(@curpos, char)
712
+ end
713
+ @curpos += 1
714
+ #$log.debug "putch INS: cp:#{@curpos}, max:#{_maxlen}, buf:(#{@buffer.length})"
715
+ if @curpos-1 > _maxlen or @buffer.length()-1 > _maxlen
716
+ lastchars, lastspace = push_last_word @current_index
717
+ #$log.debug "last sapce #{lastspace}, lastchars:#{lastchars},lc:#{lastchars[-1]}, #{@list[@current_index]} "
718
+ ## wrap on word XX If last char is 10 then insert line
719
+ @buffer = @list[@current_index]
720
+ if @curpos-1 > _maxlen or @curpos-1 > @buffer.length()-1
721
+ ret = down
722
+ # keep the cursor in the same position in the string that was pushed down.
723
+ @curpos = oldcurpos - lastspace #lastchars.length # 0
724
+ end
725
+ end
726
+ set_form_row
727
+ @buffer = @list[@current_index]
728
+ set_form_col
729
+ @modified = true
730
+ fire_handler :CHANGE, InputDataEvent.new(oldcurpos,@curpos, self, :INSERT, @current_index, char) # 2008-12-24 18:34
731
+ @repaint_required = true
732
+ 0
733
+ end
734
+ # removes and returns last word in given line number, or nil if no whitespace
735
+ def remove_last_word lineno
736
+ @list[lineno].chomp!
737
+ line=@list[lineno]
738
+ lastspace = line.rindex(" ")
739
+ if !lastspace.nil?
740
+ lastchars = line[lastspace+1..-1]
741
+ @list[lineno].slice!(lastspace..-1)
742
+ $log.debug " remove_last: lastspace #{lastspace},#{lastchars},#{@list[lineno]}"
743
+ fire_handler :CHANGE, InputDataEvent.new(lastspace,lastchars.length, self, :DELETE, lineno, lastchars) # 2008-12-26 23:06
744
+ return lastchars
745
+ end
746
+ return nil
747
+ end
748
+
749
+ def putc c
750
+ if c >= 32 and c <= 126
751
+ begin
752
+ ret = putch c.chr
753
+ rescue => ex
754
+ # this does not prevent entry, it prevents updating
755
+ # often comes here if error in event block, not our fault
756
+ Ncurses.beep
757
+ $log.debug " ERROR IN PUTCH RTEXTAREA "
758
+ $log.debug( ex) if ex
759
+ $log.debug(ex.backtrace.join("\n")) if ex
760
+ end
761
+ if ret == 0
762
+ # addcol 1
763
+ set_modified
764
+ return 0
765
+ end
766
+ end
767
+ return :UNHANDLED
768
+ end
769
+ # move up one char from next row to current, used when deleting in a line
770
+ # should not be called if line ends in "\r"
771
+ def move_char_up
772
+ @list[@current_index] << @list[@current_index+1].slice!(0)
773
+ delete_line(@current_index+1) if next_line().length==0
774
+ end
775
+ # tries to move up as many as possible
776
+ # should not be called if line ends in "\r"
777
+ def move_chars_up
778
+ oldprow = @current_index
779
+ oldcurpos = @curpos
780
+ _maxlen = @maxlen || @width - @internal_width
781
+ space_left = _maxlen - @buffer.length
782
+ can_move = [space_left, next_line.length].min
783
+ carry_up = @list[@current_index+1].slice!(0, can_move)
784
+ @list[@current_index] << carry_up
785
+ delete_line(@current_index+1) if next_line().length==0
786
+ fire_handler :CHANGE, InputDataEvent.new(oldcurpos,oldcurpos+can_move, self, :INSERT, oldprow, carry_up) # 2008-12-24 18:34
787
+ end
788
+ ## returns next line, does not move to it,
789
+ def next_line
790
+ @list[@current_index+1]
791
+ end
792
+ def current_line
793
+ @list[@current_index]
794
+ end
795
+ def do_relative_row num
796
+ yield @list[@current_index+num]
797
+ end
798
+ def set_modified tf=true
799
+ @modified = tf
800
+ @repaint_required = tf
801
+ @repaint_footer_required = tf
802
+ # 2010-01-14 22:45 putting a check for form, so not necessary to have form set when appending data
803
+ @form.modified = true if tf and !@form.nil?
804
+ end
805
+ def cursor_eol
806
+ _maxlen = @maxlen || @width - @internal_width
807
+ $log.error "ERROR !!! bufferlen gt _maxlen #{@buffer.length}, #{_maxlen}" if @buffer.length > _maxlen
808
+ set_form_col current_line().chomp().length() #-1 needs to be one ahead 2011-10-10 TRYING OUT XXX
809
+ end
810
+ def cursor_bol
811
+ set_form_col 0
812
+ end
813
+ #def to_s this was just annoying in debugs
814
+ def get_text
815
+ l = getvalue
816
+ str = ""
817
+ old = " "
818
+ l.each_with_index do |line, i|
819
+ tmp = line.gsub("\n","")
820
+ tmp.gsub!("\r", "\n")
821
+ if old[-1,1] !~ /\s/ and tmp[0,1] !~ /\s/
822
+ str << " "
823
+ end
824
+ str << tmp
825
+ old = tmp
826
+ end
827
+ str
828
+ end
829
+ #alias :get_text :to_s
830
+ ## ---- for listscrollable ---- ##
831
+ def scrollatrow
832
+ if @suppress_borders
833
+ @height - 1
834
+ else
835
+ @height - 3
836
+ end
837
+ end
838
+ def row_count
839
+ @list.size
840
+ end
841
+ def paint
842
+ # not sure where to put this, once for all or repeat 2010-02-12 RFED16
843
+ #my_win = @form? @form.window : @target_window
844
+ #$log.warn "neither form not target window given!!! TA paint 751" unless my_win
845
+ raise "Height or width nil h:#{@height} , w: #{@width} " if @height.nil? || @width.nil?
846
+ print_borders if (@suppress_borders == false && @repaint_all) # do this once only, unless everything changes
847
+ rc = row_count
848
+ _maxlen = @maxlen || @width-@internal_width # TODO fix in other branches remove ||=
849
+ $log.debug " #{@name} textarea repaint width is #{@width}, height is #{@height} , maxlen #{_maxlen}/ #{@maxlen}, #{@graphic.name} "
850
+ tm = get_content
851
+ tr = @toprow
852
+ acolor = get_color $datacolor
853
+ h = scrollatrow()
854
+ r,c = rowcol
855
+ @longest_line = @width # _maxlen scroll uses width not maxlen
856
+ $log.debug " TA:::: #{tr} , #{h}, r #{r} c #{c} "
857
+ 0.upto(h) do |hh|
858
+ crow = tr+hh
859
+ if crow < rc
860
+ #focussed = @current_index == crow ? true : false
861
+ #selected = is_row_selected crow
862
+ content = tm[crow].chomp rescue ""
863
+ content.gsub!(/\t/, ' ') # don't display tab
864
+ content.gsub!(/[^[:print:]]/, '') # don't display non print characters
865
+ if !content.nil?
866
+ if content.length > _maxlen # only show _maxlen
867
+ @longest_line = content.length if content.length > @longest_line
868
+ content = content[@pcol..@pcol+_maxlen-1]
869
+ else
870
+ content = content[@pcol..-1]
871
+ end
872
+ end
873
+ #renderer = get_default_cell_renderer_for_class content.class.to_s
874
+ #renderer = cell_renderer()
875
+ #renderer.repaint @form.window, r+hh, c+(colix*11), content, focussed, selected
876
+ #renderer.repaint @form.window, r+hh, c, content, focussed, selected
877
+ @graphic.printstring r+hh, c, "%-*s" % [@width-@internal_width,content], acolor, @attr
878
+ if @search_found_ix == tr+hh
879
+ if !@find_offset.nil?
880
+ @graphic.mvchgat(y=r+hh, x=c+@find_offset, @find_offset1-@find_offset, Ncurses::A_NORMAL, $reversecolor, nil)
881
+ end
882
+ end
883
+
884
+ else
885
+ # clear rows
886
+ # TODO the spaces string can be stored once outside loop
887
+ @graphic.printstring r+hh, c, " " * (@width-@internal_width), acolor,@attr
888
+ end
889
+ end
890
+ show_caret_func
891
+
892
+ @table_changed = false
893
+ @repaint_required = false
894
+ @repaint_footer_required = true # 2010-01-23 22:41
895
+ @repaint_all = false # added 2010-01-14 for redrawing everything
896
+ end
897
+ def ask_search_forward
898
+ regex = get_string("Enter regex to search", 20, @last_regex||"")
899
+ ix = _find_next regex, @current_index
900
+ if ix.nil?
901
+ alert("No matching data for: #{regex}")
902
+ else
903
+ set_focus_on(ix)
904
+ set_form_col @find_offset
905
+ end
906
+ end
907
+ def undo
908
+ if @undo_handler
909
+ @undo_handler.undo
910
+ else
911
+ undo_delete
912
+ end
913
+ end
914
+ def text_redo
915
+ return unless @undo_handler
916
+ @undo_handler.redo
917
+ end
918
+ end # class textarea
919
+ ##
920
+ end # modul