rbcurse 1.4.1 → 1.5.0.pre1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (192) hide show
  1. data/CHANGELOG +31 -0
  2. data/README.markdown +69 -11
  3. data/VERSION +1 -1
  4. data/lib/rbcurse.rb +5 -5
  5. metadata +10 -198
  6. data/Makefile +0 -21
  7. data/Manifest.txt +0 -91
  8. data/TODO +0 -372
  9. data/TODO2.txt +0 -118
  10. data/examples/README.txt +0 -67
  11. data/examples/abasiclist.rb +0 -33
  12. data/examples/alpmenu.rb +0 -42
  13. data/examples/app.rb +0 -859
  14. data/examples/app.sample +0 -10
  15. data/examples/appdirtree.rb +0 -75
  16. data/examples/appemail.rb +0 -191
  17. data/examples/appemaillb.rb +0 -308
  18. data/examples/appgcompose.rb +0 -315
  19. data/examples/atree.rb +0 -64
  20. data/examples/common/file.rb +0 -40
  21. data/examples/common/rmail.rb +0 -257
  22. data/examples/data.txt +0 -683
  23. data/examples/data/README.markdown +0 -9
  24. data/examples/data/brew.txt +0 -38
  25. data/examples/data/color.2 +0 -37
  26. data/examples/data/gemlist.txt +0 -60
  27. data/examples/data/lotr.txt +0 -12
  28. data/examples/data/ports.txt +0 -136
  29. data/examples/data/tasks.txt +0 -27
  30. data/examples/data/todocsv.csv +0 -28
  31. data/examples/data/unix1.txt +0 -21
  32. data/examples/data/unix2.txt +0 -11
  33. data/examples/dbdemo.rb +0 -495
  34. data/examples/deprecated/appgmail.rb +0 -952
  35. data/examples/deprecated/splitp.rb +0 -56
  36. data/examples/deprecated/testscrolllb.rb +0 -86
  37. data/examples/deprecated/testscrollp.rb +0 -88
  38. data/examples/deprecated/testscrollta.rb +0 -80
  39. data/examples/deprecated/testscrolltable.rb +0 -165
  40. data/examples/deprecated/testsplit.rb +0 -87
  41. data/examples/deprecated/testsplit2.rb +0 -123
  42. data/examples/deprecated/testsplit3.rb +0 -215
  43. data/examples/deprecated/testsplit3_1.rb +0 -244
  44. data/examples/deprecated/testsplit3a.rb +0 -215
  45. data/examples/deprecated/testsplit3b.rb +0 -237
  46. data/examples/deprecated/testsplitta.rb +0 -148
  47. data/examples/deprecated/testsplittv.rb +0 -142
  48. data/examples/deprecated/testsplittvv.rb +0 -144
  49. data/examples/deprecated/testtpane.rb +0 -215
  50. data/examples/deprecated/testtpane2.rb +0 -145
  51. data/examples/deprecated/testtpanetable.rb +0 -203
  52. data/examples/dirtree.rb +0 -88
  53. data/examples/experimental/resultsetdemo.rb +0 -280
  54. data/examples/experimental/testmform.rb +0 -35
  55. data/examples/experimental/testscroller.rb +0 -117
  56. data/examples/experimental/teststackflow.rb +0 -111
  57. data/examples/menu1.rb +0 -112
  58. data/examples/multispl.rb +0 -86
  59. data/examples/newmessagebox.rb +0 -130
  60. data/examples/newtabbedwindow.rb +0 -100
  61. data/examples/newtesttabp.rb +0 -121
  62. data/examples/qdfilechooser.rb +0 -68
  63. data/examples/rfe.rb +0 -1195
  64. data/examples/rfe_renderer.rb +0 -121
  65. data/examples/sqlc.rb +0 -454
  66. data/examples/sqlm.rb +0 -437
  67. data/examples/sqlt.rb +0 -408
  68. data/examples/status.txt +0 -68
  69. data/examples/table1.rb +0 -24
  70. data/examples/term2.rb +0 -84
  71. data/examples/test1.rb +0 -239
  72. data/examples/test2.rb +0 -674
  73. data/examples/testapp.rb +0 -44
  74. data/examples/testapp2.rb +0 -58
  75. data/examples/testchars.rb +0 -137
  76. data/examples/testcombo.rb +0 -91
  77. data/examples/testkeypress.rb +0 -66
  78. data/examples/testlistbox.rb +0 -113
  79. data/examples/testmenu.rb +0 -101
  80. data/examples/testmulticomp.rb +0 -70
  81. data/examples/testmulticontainer.rb +0 -94
  82. data/examples/testmultispl.rb +0 -199
  83. data/examples/testree.rb +0 -106
  84. data/examples/testtable.rb +0 -263
  85. data/examples/testtabp.rb +0 -107
  86. data/examples/testtodo.rb +0 -584
  87. data/examples/testvimsplit.rb +0 -112
  88. data/examples/testwsshortcuts.rb +0 -64
  89. data/examples/testwsshortcuts2.rb +0 -126
  90. data/examples/todo.db +0 -0
  91. data/examples/todo.yml +0 -191
  92. data/examples/viewtodo.rb +0 -574
  93. data/lib/rbcurse/action.rb +0 -40
  94. data/lib/rbcurse/app.rb +0 -1374
  95. data/lib/rbcurse/applicationheader.rb +0 -102
  96. data/lib/rbcurse/celleditor.rb +0 -112
  97. data/lib/rbcurse/checkboxcellrenderer.rb +0 -57
  98. data/lib/rbcurse/colormap.rb +0 -159
  99. data/lib/rbcurse/comboboxcellrenderer.rb +0 -30
  100. data/lib/rbcurse/common/ansiparser.rb +0 -117
  101. data/lib/rbcurse/common/appmethods.rb +0 -112
  102. data/lib/rbcurse/common/basestack.rb +0 -407
  103. data/lib/rbcurse/common/bordertitle.rb +0 -41
  104. data/lib/rbcurse/common/chunk.rb +0 -177
  105. data/lib/rbcurse/common/colorparser.rb +0 -71
  106. data/lib/rbcurse/common/keydefs.rb +0 -30
  107. data/lib/rbcurse/common/widgetshortcuts.rb +0 -302
  108. data/lib/rbcurse/defaultlistselectionmodel.rb +0 -79
  109. data/lib/rbcurse/deprecated/README.markdown +0 -12
  110. data/lib/rbcurse/deprecated/rscrollpane.rb +0 -512
  111. data/lib/rbcurse/deprecated/rsplitpane.rb +0 -894
  112. data/lib/rbcurse/deprecated/rsplitpane2.rb +0 -1009
  113. data/lib/rbcurse/deprecated/rviewport.rb +0 -204
  114. data/lib/rbcurse/experimental/README.markdown +0 -14
  115. data/lib/rbcurse/experimental/resultsettextview.rb +0 -585
  116. data/lib/rbcurse/experimental/stackflow.rb +0 -478
  117. data/lib/rbcurse/extras/bottomline.rb +0 -1850
  118. data/lib/rbcurse/extras/box.rb +0 -58
  119. data/lib/rbcurse/extras/directorylist.rb +0 -467
  120. data/lib/rbcurse/extras/directorytree.rb +0 -69
  121. data/lib/rbcurse/extras/divider.rb +0 -310
  122. data/lib/rbcurse/extras/focusmanager.rb +0 -31
  123. data/lib/rbcurse/extras/horizlist.rb +0 -203
  124. data/lib/rbcurse/extras/listselectable.rb +0 -264
  125. data/lib/rbcurse/extras/masterdetail.rb +0 -166
  126. data/lib/rbcurse/extras/menutree.rb +0 -63
  127. data/lib/rbcurse/extras/multiform.rb +0 -330
  128. data/lib/rbcurse/extras/multilinelabel.rb +0 -142
  129. data/lib/rbcurse/extras/newmessagebox.rb +0 -328
  130. data/lib/rbcurse/extras/newtabbedpane.rb +0 -612
  131. data/lib/rbcurse/extras/newtabbedwindow.rb +0 -68
  132. data/lib/rbcurse/extras/padreader.rb +0 -189
  133. data/lib/rbcurse/extras/rcomboedit.rb +0 -256
  134. data/lib/rbcurse/extras/resultsetbrowser.rb +0 -281
  135. data/lib/rbcurse/extras/rlink.rb +0 -27
  136. data/lib/rbcurse/extras/rmenulink.rb +0 -21
  137. data/lib/rbcurse/extras/scrollbar.rb +0 -143
  138. data/lib/rbcurse/extras/statusline.rb +0 -94
  139. data/lib/rbcurse/extras/stdscrwindow.rb +0 -309
  140. data/lib/rbcurse/extras/tableextended.rb +0 -40
  141. data/lib/rbcurse/extras/tabular.rb +0 -264
  142. data/lib/rbcurse/extras/tabularwidget.rb +0 -1150
  143. data/lib/rbcurse/extras/textpad.rb +0 -516
  144. data/lib/rbcurse/extras/viewer.rb +0 -136
  145. data/lib/rbcurse/io.rb +0 -850
  146. data/lib/rbcurse/keylabelprinter.rb +0 -178
  147. data/lib/rbcurse/listcellrenderer.rb +0 -140
  148. data/lib/rbcurse/listeditable.rb +0 -310
  149. data/lib/rbcurse/listkeys.rb +0 -37
  150. data/lib/rbcurse/listscrollable.rb +0 -564
  151. data/lib/rbcurse/listselectable.rb +0 -142
  152. data/lib/rbcurse/mapper.rb +0 -130
  153. data/lib/rbcurse/orderedhash.rb +0 -77
  154. data/lib/rbcurse/ractionevent.rb +0 -67
  155. data/lib/rbcurse/rbasiclistbox.rb +0 -768
  156. data/lib/rbcurse/rchangeevent.rb +0 -27
  157. data/lib/rbcurse/rcombo.rb +0 -238
  158. data/lib/rbcurse/rcommandwindow.rb +0 -587
  159. data/lib/rbcurse/rcontainer.rb +0 -415
  160. data/lib/rbcurse/rdialogs.rb +0 -451
  161. data/lib/rbcurse/rinputdataevent.rb +0 -47
  162. data/lib/rbcurse/rlistbox.rb +0 -1196
  163. data/lib/rbcurse/rmenu.rb +0 -939
  164. data/lib/rbcurse/rmessagebox.rb +0 -348
  165. data/lib/rbcurse/rmulticontainer.rb +0 -304
  166. data/lib/rbcurse/rmultisplit.rb +0 -722
  167. data/lib/rbcurse/rmultitextview.rb +0 -306
  168. data/lib/rbcurse/rpopupmenu.rb +0 -755
  169. data/lib/rbcurse/rprogress.rb +0 -118
  170. data/lib/rbcurse/rscrollform.rb +0 -418
  171. data/lib/rbcurse/rtabbedpane.rb +0 -1158
  172. data/lib/rbcurse/rtabbedwindow.rb +0 -167
  173. data/lib/rbcurse/rtable.rb +0 -1718
  174. data/lib/rbcurse/rtextarea.rb +0 -920
  175. data/lib/rbcurse/rtextview.rb +0 -761
  176. data/lib/rbcurse/rtree.rb +0 -780
  177. data/lib/rbcurse/rvimsplit.rb +0 -763
  178. data/lib/rbcurse/rwidget.rb +0 -2915
  179. data/lib/rbcurse/scrollable.rb +0 -301
  180. data/lib/rbcurse/table/tablecellrenderer.rb +0 -86
  181. data/lib/rbcurse/table/tabledatecellrenderer.rb +0 -98
  182. data/lib/rbcurse/tree/treecellrenderer.rb +0 -150
  183. data/lib/rbcurse/tree/treemodel.rb +0 -428
  184. data/lib/rbcurse/undomanager.rb +0 -188
  185. data/lib/rbcurse/vieditable.rb +0 -144
  186. data/lib/ver/keyboard.rb +0 -150
  187. data/lib/ver/keyboard2.rb +0 -170
  188. data/lib/ver/ncurses.rb +0 -218
  189. data/lib/ver/panel.rb +0 -162
  190. data/lib/ver/rpad.rb +0 -375
  191. data/lib/ver/window.rb +0 -882
  192. data/test/test_rbcurse.rb +0 -0
@@ -1,761 +0,0 @@
1
- =begin
2
- * Name: TextView
3
- * Description View text in this widget.
4
- * Author: rkumar (arunachalesha)
5
- * file created 2009-01-08 15:23
6
- * major change: 2010-02-10 19:43 simplifying the buffer stuff.
7
- TODO
8
- * border, and footer could be objects (classes) at some future stage.
9
- --------
10
- * License:
11
- Same as Ruby's License (http://www.ruby-lang.org/LICENSE.txt)
12
-
13
- =end
14
- require 'logger'
15
- require 'rbcurse'
16
- require 'rbcurse/listscrollable'
17
-
18
- include RubyCurses
19
- module RubyCurses
20
- extend self
21
-
22
- ##
23
- # A viewable read only box. Can scroll.
24
- # Intention is to be able to change content dynamically - the entire list.
25
- # Use set_content to set content, or just update the list attrib
26
- # TODO -
27
- # - goto line - DONE
28
- class TextView < Widget
29
- include ListScrollable
30
- #dsl_accessor :height # height of viewport cmmented on 2010-01-09 19:29 since widget has method
31
- dsl_accessor :title # set this on top
32
- dsl_accessor :title_attrib # bold, reverse, normal
33
- dsl_accessor :footer_attrib # bold, reverse, normal
34
- dsl_accessor :list # the array of data to be sent by user
35
- dsl_accessor :maxlen # max len to be displayed
36
- attr_reader :toprow # the toprow in the view (offsets are 0)
37
- # attr_reader :prow # the row on which cursor/focus is
38
- #attr_reader :winrow # the row in the viewport/window
39
- # painting the footer does slow down cursor painting slightly if one is moving cursor fast
40
- dsl_accessor :print_footer
41
- dsl_accessor :suppress_borders # added 2010-02-10 20:05 values true or false
42
- attr_reader :current_index
43
- dsl_accessor :border_attrib, :border_color #
44
- dsl_accessor :sanitization_required
45
-
46
- def initialize form = nil, config={}, &block
47
- @focusable = true
48
- @editable = false
49
- @sanitization_required = true
50
- @suppress_borders = false
51
- @row_offset = @col_offset = 1
52
- @row = 0
53
- @col = 0
54
- @show_focus = false # don't highlight row under focus
55
- @list = []
56
- super
57
- # ideally this should have been 2 to take care of borders, but that would break
58
- # too much stuff !
59
- @win = @graphic
60
-
61
- @_events.push :CHANGE # thru vieditable
62
- @_events << :PRESS # new, in case we want to use this for lists and allow ENTER
63
- @_events << :ENTER_ROW # new, should be there in listscrollable ??
64
- install_keys # do something about this nonsense FIXME
65
- init_vars
66
- map_keys
67
- end
68
- def init_vars #:nodoc:
69
- @curpos = @pcol = @toprow = @current_index = 0
70
- @repaint_all=true
71
- @repaint_required=true
72
- @widget_scrolled = true
73
- ## 2010-02-10 20:20 RFED16 taking care if no border requested
74
- @row_offset = @col_offset = 0 if @suppress_borders == true
75
- # added 2010-02-11 15:11 RFED16 so we don't need a form.
76
- $error_message_row ||= 23
77
- $error_message_col ||= 1
78
- # currently i scroll right only if current line is longer than display width, i should use
79
- # longest line on screen.
80
- @longest_line = 0 # the longest line printed on this page, used to determine if scrolling shd work
81
- @internal_width = 2
82
- @internal_width = 0 if @suppress_borders
83
-
84
- end
85
- def map_keys
86
- bind_key([?g,?g]){ goto_start } # mapping double keys like vim
87
- bind_key([?',?']){ goto_last_position } # vim , goto last row position (not column)
88
- bind_key(?/, :ask_search)
89
- bind_key(?n, :find_more)
90
- bind_key([?\C-x, ?>], :scroll_right)
91
- bind_key([?\C-x, ?<], :scroll_left)
92
- bind_key(?\M-l, :scroll_right)
93
- bind_key(?\M-h, :scroll_left)
94
- bind_key([?\C-x, ?\C-s], :saveas)
95
- #bind_key(?r) { getstr("Enter a word: ") }
96
- bind_key(?m, :disp_menu)
97
- end
98
- ##
99
- # send in a list
100
- # e.g. set_content File.open("README.txt","r").readlines
101
- # set wrap at time of passing :WRAP_NONE :WRAP_WORD
102
- # XXX if we widen the textview later, as in a vimsplit that data
103
- # will still be wrapped at this width !!
104
- def set_content list, wrap = :WRAP_NONE
105
- @wrap_policy = wrap
106
- if list.is_a? String
107
- if @wrap_policy == :WRAP_WORD
108
- data = wrap_text list
109
- @list = data.split("\n")
110
- else
111
- @list = list.split("\n")
112
- end
113
- elsif list.is_a? Array
114
- if @wrap_policy == :WRAP_WORD
115
- data = wrap_text list.join(" ")
116
- @list = data.split("\n")
117
- else
118
- @list = list
119
- end
120
- else
121
- raise "set_content expects Array not #{list.class}"
122
- end
123
- init_vars
124
- end
125
- # for consistency with other objects that respect text
126
- alias :text :set_content
127
- def formatted_text text, fmt
128
- require 'rbcurse/common/chunk'
129
- @formatted_text = text
130
- @color_parser = fmt
131
- remove_all
132
- end
133
-
134
- def remove_all
135
- @list = []
136
- init_vars
137
- @repaint_required = true
138
- end
139
- ## display this row on top
140
- def top_row(*val) #:nodoc:
141
- if val.empty?
142
- @toprow
143
- else
144
- @toprow = val[0] || 0
145
- end
146
- @repaint_required = true
147
- end
148
- ## ---- for listscrollable ---- ##
149
- def scrollatrow #:nodoc:
150
- if @suppress_borders
151
- @height - 1 # should be 2 FIXME but erasing lower line. see appemail
152
- else
153
- @height - 3
154
- end
155
- end
156
- def row_count
157
- @list.length
158
- end
159
- ##
160
- # returns row of first match of given regex (or nil if not found)
161
- def find_first_match regex #:nodoc:
162
- @list.each_with_index do |row, ix|
163
- return ix if !row.match(regex).nil?
164
- end
165
- return nil
166
- end
167
- ## returns the position where cursor was to be positioned by default
168
- # It may no longer work like that.
169
- def rowcol #:nodoc:
170
- return @row+@row_offset, @col+@col_offset
171
- end
172
- def wrap_text(txt, col = @maxlen) #:nodoc:
173
- col ||= @width-@internal_width
174
- #$log.debug "inside wrap text for :#{txt}"
175
- txt.gsub(/(.{1,#{col}})( +|$\n?)|(.{1,#{col}})/,
176
- "\\1\\3\n")
177
- end
178
- ## print a border
179
- ## Note that print_border clears the area too, so should be used sparingly.
180
- def print_borders #:nodoc:
181
- raise "textview needs width" unless @width
182
- raise "textview needs height" unless @height
183
-
184
- $log.debug " #{@name} print_borders, #{@graphic.name} "
185
-
186
- @color_pair = get_color($datacolor) # added 2011-09-28 as in rlistbox
187
- # bordercolor = @border_color || $datacolor # changed 2011 dts
188
- bordercolor = @border_color || @color_pair # 2011-09-28 V1.3.1
189
- borderatt = @border_attrib || Ncurses::A_NORMAL
190
- @graphic.print_border @row, @col, @height-1, @width, bordercolor, borderatt
191
- print_title
192
- end
193
- def print_title #:nodoc:
194
- return unless @title
195
- raise "textview needs width" unless @width
196
- @color_pair ||= get_color($datacolor) # should we not use this ??? XXX
197
-
198
- # check title.length and truncate if exceeds width
199
- _title = @title
200
- if @title.length > @width - 2
201
- _title = @title[0..@width-2]
202
- end
203
- @graphic.printstring( @row, @col+(@width-_title.length)/2, _title, @color_pair, @title_attrib) unless @title.nil?
204
- end
205
- def print_foot #:nodoc:
206
- @footer_attrib ||= Ncurses::A_REVERSE
207
- footer = "R: #{@current_index+1}, C: #{@curpos+@pcol}, #{@list.length} lines "
208
- $log.debug " print_foot calling printstring with #{@row} + #{@height} -1, #{@col}+2"
209
- @graphic.printstring( @row + @height -1 , @col+2, footer, @color_pair || $datacolor, @footer_attrib)
210
- @repaint_footer_required = false # 2010-01-23 22:55
211
- end
212
- ### FOR scrollable ###
213
- def get_content
214
- @list
215
- end
216
- def get_window #:nodoc:
217
- @graphic
218
- end
219
-
220
- def repaint # textview :nodoc:
221
- #$log.debug "TEXTVIEW repaint r c #{@row}, #{@col}, key: #{$current_key}, reqd #{@repaint_required} "
222
-
223
- #return unless @repaint_required # 2010-02-12 19:08 TRYING - won't let footer print for col move
224
- # TRYING OUT dangerous 2011-10-13
225
- @repaint_required = false
226
- @repaint_required = true if @widget_scrolled || @pcol != @old_pcol || @record_changed || @property_changed
227
-
228
- paint if @repaint_required
229
-
230
- @repaint_footer_required = true if @oldrow != @current_index # 2011-10-15
231
- print_foot if @print_footer && !@suppress_borders && @repaint_footer_required
232
- end
233
- def getvalue
234
- @list
235
- end
236
- def current_value
237
- @list[@current_index]
238
- end
239
-
240
- # determine length of row since we have chunks now.
241
- # Since chunk implements length, so not required except for the old
242
- # cases of demos that use an array.
243
- def row_length
244
- case @buffer
245
- when String
246
- @buffer.length
247
- when Chunks::ChunkLine
248
- return @buffer.length
249
- when Array
250
- # this is for those old cases like rfe.rb which sent in an array
251
- # (before we moved to chunks)
252
- # line is an array of arrays
253
- if @buffer[0].is_a? Array
254
- result = 0
255
- @buffer.each {|e| result += e[1].length }
256
- return result
257
- end
258
- # line is one single chunk
259
- return @buffer[1].length
260
- end
261
- end
262
- # textview
263
- # NOTE: i think this should return if list is nil or empty. No need to put
264
- #
265
- # stuff into buffer and continue. will trouble other classes that extend.
266
- def handle_key ch #:nodoc:
267
- $log.debug " textview got ch #{ch} "
268
- @old_pcol = @pcol
269
- @buffer = @list[@current_index]
270
- if @buffer.nil? and row_count == 0
271
- @list << "\r"
272
- @buffer = @list[@current_index]
273
- end
274
- return if @buffer.nil?
275
- #$log.debug " before: curpos #{@curpos} blen: #{row_length}"
276
- if @curpos > row_length #@buffer.length
277
- addcol((row_length-@curpos)+1)
278
- @curpos = row_length
279
- set_form_col
280
- end
281
- # We can improve later
282
- case ch
283
- when ?\C-n.getbyte(0), 32
284
- scroll_forward
285
- when ?\C-p.getbyte(0)
286
- scroll_backward
287
- when ?\C-[.getbyte(0), ?t.getbyte(0)
288
- goto_start #start of buffer # cursor_start
289
- when ?\C-].getbyte(0), ?G.getbyte(0)
290
- goto_end # end / bottom cursor_end
291
- when KEY_UP, ?k.getbyte(0)
292
- #select_prev_row
293
- ret = up
294
- # next removed as very irritating, can be configured if required 2011-11-2
295
- #get_window.ungetch(KEY_BTAB) if ret == :NO_PREVIOUS_ROW
296
- check_curpos
297
-
298
- when KEY_DOWN, ?j.getbyte(0)
299
- ret = down
300
- # This should be configurable, or only if all rows are visible
301
- #get_window.ungetch(KEY_TAB) if ret == :NO_NEXT_ROW
302
- check_curpos
303
- when KEY_LEFT, ?h.getbyte(0)
304
- cursor_backward
305
- when KEY_RIGHT, ?l.getbyte(0)
306
- cursor_forward
307
- when KEY_BACKSPACE, KEY_BSPACE, KEY_DELETE
308
- cursor_backward
309
- when ?\C-a.getbyte(0) #, ?0.getbyte(0)
310
- # take care of data that exceeds maxlen by scrolling and placing cursor at start
311
- @repaint_required = true if @pcol > 0 # tried other things but did not work
312
- set_form_col 0
313
- @pcol = 0
314
- when ?\C-e.getbyte(0), ?$.getbyte(0)
315
- # take care of data that exceeds maxlen by scrolling and placing cursor at end
316
- # This use to actually pan the screen to actual end of line, but now somewhere
317
- # it only goes to end of visible screen, set_form probably does a sanity check
318
- blen = row_length # @buffer.rstrip.length FIXME
319
- set_form_col blen
320
- # search related
321
- when @KEY_ASK_FIND
322
- ask_search
323
- when @KEY_FIND_MORE
324
- find_more
325
- when 10, 13, KEY_ENTER
326
- #fire_handler :PRESS, self
327
- fire_action_event
328
- when ?0.getbyte(0)..?9.getbyte(0)
329
- # FIXME the assumption here was that if numbers are being entered then a 0 is a number
330
- # not a beg-of-line command.
331
- # However, after introducing universal_argument, we can enters numbers using C-u and then press another
332
- # C-u to stop. In that case a 0 should act as a command, even though multiplier has been set
333
- if ch == ?0.getbyte(0) and $multiplier == 0
334
- # copy of C-a - start of line
335
- @repaint_required = true if @pcol > 0 # tried other things but did not work
336
- set_form_col 0
337
- @pcol = 0
338
- return 0
339
- end
340
- # storing digits entered so we can multiply motion actions
341
- $multiplier *= 10 ; $multiplier += (ch-48)
342
- return 0
343
- when ?\C-c.getbyte(0)
344
- $multiplier = 0
345
- return 0
346
- else
347
- # check for bindings, these cannot override above keys since placed at end
348
- begin
349
- ret = process_key ch, self
350
- rescue => err
351
- $log.error " TEXTVIEW ERROR #{err} "
352
- $log.debug(err.backtrace.join("\n"))
353
- alert err.to_s
354
- end
355
- return :UNHANDLED if ret == :UNHANDLED
356
- end
357
- $multiplier = 0 # you must reset if you've handled a key. if unhandled, don't reset since parent could use
358
- set_form_row
359
- return 0 # added 2010-01-12 22:17 else down arrow was going into next field
360
- end
361
- # newly added to check curpos when moving up or down
362
- def check_curpos #:nodoc:
363
- @buffer = @list[@current_index]
364
- # if the cursor is ahead of data in this row then move it back
365
- if @pcol+@curpos > row_length
366
- addcol((@pcol+row_length-@curpos)+1)
367
- @curpos = row_length
368
- maxlen = (@maxlen || @width-@internal_width)
369
-
370
- # even this row is gt maxlen, i.e., scrolled right
371
- if @curpos > maxlen
372
- @pcol = @curpos - maxlen
373
- @curpos = maxlen-1
374
- else
375
- # this row is within maxlen, make scroll 0
376
- @pcol=0
377
- end
378
- set_form_col
379
- end
380
- end
381
- # set cursor on correct column tview
382
- def set_form_col col1=@curpos #:nodoc:
383
- @cols_panned ||= 0
384
- @pad_offset ||= 0 # added 2010-02-11 21:54 since padded widgets get an offset.
385
- @curpos = col1
386
- maxlen = @maxlen || @width-@internal_width
387
- #@curpos = maxlen if @curpos > maxlen
388
- if @curpos > maxlen
389
- @pcol = @curpos - maxlen
390
- @curpos = maxlen - 1
391
- @repaint_required = true # this is required so C-e can pan screen
392
- else
393
- @pcol = 0
394
- end
395
- # the rest only determines cursor placement
396
- win_col = 0 # 2010-02-07 23:19 new cursor stuff
397
- col2 = win_col + @col + @col_offset + @curpos + @cols_panned + @pad_offset
398
- $log.debug "TV SFC #{@name} setting c to #{col2} #{win_col} #{@col} #{@col_offset} #{@curpos} "
399
- #@form.setrowcol @form.row, col
400
- setrowcol nil, col2
401
- @repaint_footer_required = true
402
- end
403
- def cursor_forward #:nodoc:
404
- maxlen = @maxlen || @width-@internal_width
405
- repeatm {
406
- if @curpos < @width and @curpos < maxlen-1 # else it will do out of box
407
- @curpos += 1
408
- addcol 1
409
- else
410
- @pcol += 1 if @pcol <= row_length
411
- end
412
- }
413
- set_form_col
414
- #@repaint_required = true
415
- @repaint_footer_required = true # 2010-01-23 22:41
416
- end
417
- def addcol num #:nodoc:
418
- #@repaint_required = true
419
- @repaint_footer_required = true # 2010-01-23 22:41
420
- if @form
421
- @form.addcol num
422
- else
423
- @parent_component.form && @parent_component.form.addcol(num)
424
- end
425
- end
426
- def addrowcol row,col #:nodoc:
427
- #@repaint_required = true
428
- @repaint_footer_required = true # 2010-01-23 22:41
429
- if @form
430
- @form.addrowcol row, col
431
- else
432
- @parent_component.form.addrowcol num
433
- end
434
- end
435
- def cursor_backward #:nodoc:
436
- repeatm {
437
- if @curpos > 0
438
- @curpos -= 1
439
- set_form_col
440
- #addcol -1
441
- elsif @pcol > 0
442
- @pcol -= 1
443
- end
444
- }
445
- #@repaint_required = true
446
- @repaint_footer_required = true # 2010-01-23 22:41
447
- end
448
- # gives offset of next line, does not move
449
- # @deprecated
450
- def next_line #:nodoc:
451
- @list[@current_index+1]
452
- end
453
- # @deprecated
454
- def do_relative_row num #:nodoc:
455
- raise "unused will be removed"
456
- yield @list[@current_index+num]
457
- end
458
-
459
- # supply with a color parser, if you supplied formatted text
460
- def color_parser f
461
- $log.debug "XXX: parser setting color_parser to #{f} "
462
- #@window.color_parser f
463
- @color_parser = f
464
- end
465
-
466
-
467
-
468
- ## NOTE: earlier print_border was called only once in constructor, but when
469
- ##+ a window is resized, and destroyed, then this was never called again, so the
470
- ##+ border would not be seen in splitpane unless the width coincided exactly with
471
- ##+ what is calculated in divider_location.
472
- def paint #:nodoc:
473
-
474
- $log.debug "XXX TEXTVIEW repaint HAPPENING #{@current_index} "
475
- my_win = nil
476
- if @form
477
- my_win = @form.window
478
- else
479
- my_win = @target_window
480
- end
481
- @graphic = my_win unless @graphic
482
- if @formatted_text
483
- $log.debug "XXX: INSIDE FORMATTED TEXT "
484
-
485
- # I don't want to do this in 20 places and then have to change
486
- # it and retest. Let me push it to util.
487
- l = RubyCurses::Utils.parse_formatted_text(@color_parser,
488
- @formatted_text)
489
-
490
- #cp = Chunks::ColorParser.new @color_parser
491
- #l = []
492
- #@formatted_text.each { |e| l << cp.convert_to_chunk(e) }
493
-
494
- text(l)
495
- @formatted_text = nil
496
-
497
- end
498
-
499
- print_borders if (@suppress_borders == false && @repaint_all) # do this once only, unless everything changes
500
- rc = row_count
501
- maxlen = @maxlen || @width-@internal_width
502
- #$log.debug " #{@name} textview repaint width is #{@width}, height is #{@height} , maxlen #{maxlen}/ #{@maxlen}, #{@graphic.name} roff #{@row_offset} coff #{@col_offset}"
503
- tm = get_content
504
- tr = @toprow
505
- acolor = get_color $datacolor
506
- h = scrollatrow()
507
- r,c = rowcol
508
- @longest_line = @width-@internal_width #maxlen
509
- 0.upto(h) do |hh|
510
- crow = tr+hh
511
- if crow < rc
512
- #focussed = @current_index == crow ? true : false
513
- #selected = is_row_selected crow
514
- content = tm[crow]
515
- # next call modified string. you may wanna dup the string.
516
- # rlistbox does
517
- # scrolling fails if you do not dup, since content gets truncated
518
- if content.is_a? String
519
- content = content.dup
520
- sanitize(content) if @sanitization_required
521
- truncate content
522
- @graphic.printstring r+hh, c, "%-*s" % [@width-@internal_width,content],
523
- acolor, @attr
524
- elsif content.is_a? Chunks::ChunkLine
525
- @graphic.printstring r+hh, c, " "* (@width-@internal_width),
526
- acolor, @attr
527
- @graphic.wmove r+hh, c
528
- # either we have to loop through and put in default color and attr
529
- # or pass it to show_col
530
- a = get_attrib @attrib
531
- # FIXME this does not clear till the eol
532
- @graphic.show_colored_chunks content, acolor, a
533
- elsif content.is_a? Chunks::Chunk
534
- raise "TODO chunk in textview"
535
- elsif content.is_a? Array
536
- # several chunks in one row - NOTE Very experimental may change
537
- if content[0].is_a? Array
538
- # clearing the line since colored_chunks does not yet XXX FIXME if possible
539
- @graphic.printstring r+hh, c, " "* (@width-@internal_width),
540
- acolor, @attr
541
- @graphic.wmove r+hh, c
542
- # either we have to loop through and put in default color and attr
543
- # or pass it to show_col
544
- a = get_attrib @attrib
545
- # FIXME this does not clear till the eol
546
- @graphic.show_colored_chunks content, acolor, a
547
- else
548
- # a single row chunk - NOTE Very experimental may change
549
- text = content[1].dup
550
- sanitize(text) if @sanitization_required
551
- truncate text
552
- @graphic.printstring r+hh, c, "%-*s" % [@width-@internal_width,text],
553
- content[0] || acolor, content[2] || @attr
554
- end
555
- end
556
-
557
- # highlighting search results.
558
- if @search_found_ix == tr+hh
559
- if !@find_offset.nil?
560
- # handle exceed bounds, and if scrolling
561
- if @find_offset1 < maxlen+@pcol and @find_offset > @pcol
562
- @graphic.mvchgat(y=r+hh, x=c+@find_offset-@pcol, @find_offset1-@find_offset, Ncurses::A_NORMAL, $reversecolor, nil)
563
- end
564
- end
565
- end
566
-
567
- else
568
- # clear rows
569
- @graphic.printstring r+hh, c, " " * (@width-@internal_width), acolor,@attr
570
- end
571
- end
572
-
573
-
574
- @repaint_required = false
575
- @repaint_footer_required = true
576
- @repaint_all = false
577
- # 2011-10-15
578
- @widget_scrolled = false
579
- @record_changed = false
580
- @property_changed = false
581
- @old_pcol = @pcol
582
-
583
- end
584
- # takes a block, this way anyone extending this class can just pass a block to do his job
585
- # This modifies the string
586
- def sanitize content #:nodoc:
587
-
588
- if content.is_a? String
589
- content.chomp!
590
- # trying out since gsub giving #<ArgumentError: invalid byte sequence in UTF-8> 2011-09-11
591
-
592
- content.replace(content.encode("ASCII-8BIT", :invalid => :replace, :undef => :replace, :replace => "?")) if content.respond_to?(:encode)
593
- content.gsub!(/[\t\n\r]/, ' ') # don't display tab or newlines
594
- content.gsub!(/[^[:print:]]/, '') # don't display non print characters
595
- else
596
- content
597
- end
598
- end
599
- # returns only the visible portion of string taking into account display length
600
- # and horizontal scrolling. MODIFIES STRING
601
- def truncate content #:nodoc:
602
- _maxlen = @maxlen || @width-@internal_width
603
- _maxlen = @width-@internal_width if _maxlen > @width-@internal_width # take care of decrease in width
604
- if !content.nil?
605
- if content.length > _maxlen # only show maxlen
606
- @longest_line = content.length if content.length > @longest_line
607
- #content = content[@pcol..@pcol+maxlen-1]
608
- content.replace(content[@pcol..@pcol+_maxlen-1] || "")
609
- else
610
- if @pcol > 0
611
- content.replace(content[@pcol..-1] || "")
612
- end
613
- end
614
- end
615
- content
616
- end
617
- ## this is just a test of prompting user for a string
618
- #+ as an alternative to the dialog.
619
- def getstr prompt, maxlen=10 #:nodoc:
620
- tabc = Proc.new {|str| Dir.glob(str +"*") }
621
- config={}; config[:tab_completion] = tabc
622
- config[:default] = "default"
623
- $log.debug " inside getstr before call "
624
- ret, str = rbgetstr(@form.window, @row+@height-1, @col+1, prompt, maxlen, config)
625
- $log.debug " rbgetstr returned #{ret} , #{str} "
626
- return "" if ret != 0
627
- return str
628
- end
629
- # this is just a test of the simple "most" menu
630
- # How can application add to this, or override
631
- # TODO: use another window at bottom, statuswindow
632
- def disp_menu #:nodoc:
633
- require 'rbcurse/extras/menutree'
634
- # we need to put this into data-structure so that i can be manipulated by calling apps
635
- # This should not be at the widget level, too many types of menus. It should be at the app
636
- # level only if the user wants his app to use this kind of menu.
637
-
638
- if false
639
- #@menu = RubyCurses::MenuTree.new "Main", { s: :goto_start, r: :scroll_right, l: :scroll_left, m: :submenu }
640
- #@menu.submenu :m, "submenu", {s: :noignorecase, t: :goto_last_position, f: :next3 }
641
- #menu = PromptMenu.new self
642
- #menu.menu_tree @menu
643
- #menu.display @form.window, $error_message_row, $error_message_col, $datacolor #, menu
644
- end
645
- # trying to find a more rubyesque way of doing
646
- menu = PromptMenu.new self do
647
- item :s, :goto_start
648
- item :b, :goto_bottom
649
- item :r, :scroll_backward
650
- item :l, :scroll_forward
651
- submenu :m, "submenu..." do
652
- item :p, :goto_last_position
653
- item :r, :scroll_right
654
- item :l, :scroll_left
655
- end
656
- end
657
- #menu.display @form.window, $error_message_row, $error_message_col, $datacolor #, menu
658
- menu.display_new :title => "Menu"
659
-
660
-
661
- =begin
662
- menu = PromptMenu.new self
663
- menu.add( menu.create_mitem( 's', "Goto start ", "Going to start", Proc.new { goto_start} ))
664
- menu.add(menu.create_mitem( 'r', "scroll right", "I have scrolled ", :scroll_right ))
665
- menu.add(menu.create_mitem( 'l', "scroll left", "I have scrolled ", :scroll_left ))
666
- item = menu.create_mitem( 'm', "submenu", "submenu options" )
667
- menu1 = PromptMenu.new( self, "Submenu Options")
668
- menu1.add(menu1.create_mitem( 's', "CASE sensitive", "Ignoring Case in search" ))
669
- menu1.add(menu1.create_mitem( 't', "goto last position", "moved to previous position", Proc.new { goto_last_position} ))
670
- item.action = menu1
671
- menu.add(item)
672
- # how do i know what's available. the application or window should know where to place
673
- #menu.display @form.window, 23, 1, $datacolor #, menu
674
- =end
675
- end
676
- ##
677
- # dynamically load a module and execute init method.
678
- # Hopefully, we can get behavior like this such as vieditable or multibuffers
679
- def load_module requirename, includename
680
- require "rbcurse/#{requirename}"
681
- extend Object.const_get("#{includename}")
682
- send("#{requirename}_init") #if respond_to? "#{includename}_init"
683
- end
684
- # on pressing ENTER we send user some info, the calling program
685
- # would bind :PRESS
686
- #--
687
- # FIXME we can create this once and reuse
688
- #++
689
- def fire_action_event
690
- return if @list.nil? || @list.size == 0
691
- require 'rbcurse/ractionevent'
692
- aev = TextActionEvent.new self, :PRESS, current_value(), @current_index, @curpos
693
- fire_handler :PRESS, aev
694
- end
695
- # called by listscrollable, used by scrollbar ENTER_ROW
696
- def on_enter_row arow
697
- fire_handler :ENTER_ROW, self
698
- @repaint_required = true
699
- end
700
- # added 2010-09-30 18:48 so standard with other components, esp on enter
701
- # NOTE: the on_enter repaint required causes this to be repainted 2 times
702
- # if its the first object, once with the entire form, then with on_enter.
703
- def on_enter
704
- if @list.nil? || @list.size == 0
705
- Ncurses.beep
706
- return :UNHANDLED
707
- end
708
- on_enter_row @current_index
709
- set_form_row
710
- @repaint_required = true
711
- super
712
- true
713
- end
714
- def pipe_file
715
- # TODO ask process name from user
716
- output = pipe_output 'munpack', @list
717
- if output && !output.empty?
718
- set_content output
719
- end
720
- end
721
- # returns array of lines after running command on string passed
722
- # TODO: need to close pipe other's we'll have a process lying
723
- # around forever.
724
- def pipe_output (pipeto, str)
725
- case str
726
- when String
727
- #str = str.split "\n"
728
- # okay
729
- when Array
730
- str = str.join "\n"
731
- end
732
- #pipeto = '/usr/sbin/sendmail -t'
733
- #pipeto = %q{mail -s "my title" rahul}
734
- if pipeto != nil # i was taking pipeto from a hash, so checking
735
- proc = IO.popen(pipeto, "w+")
736
- proc.puts str
737
- proc.close_write
738
- proc.readlines
739
- end
740
- end
741
- def saveas name=nil, config={}
742
- unless name
743
- name = @graphic.ask "File to save as: "
744
- return if name.nil? || name == ""
745
- end
746
- exists = File.exists? name
747
- if exists # need to prompt
748
- return unless @graphic.agree("Overwrite existing file? ", true)
749
- end
750
- l = getvalue
751
- File.open(name, "w"){ |f|
752
- l.each { |line| f.puts line }
753
- #l.each { |line| f.write line.gsub(/\r/,"\n") }
754
- }
755
- @graphic.say "#{name} written."
756
- end
757
-
758
-
759
- end # class textview
760
-
761
- end # modul