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
data/lib/rbcurse/rtree.rb DELETED
@@ -1,780 +0,0 @@
1
- =begin
2
- * Name: rtree:
3
- * Description : a Tree control
4
- * Author: rkumar (arunachalesha)
5
- * Date: 2010-09-18 12:02
6
- * License: Same as Ruby's License (http://www.ruby-lang.org/LICENSE.txt)
7
- * This file started on 2010-09-18 12:03 (copied from rlistbox)
8
- TODO:
9
- [x] load on tree will expand
10
- [x] selected row on startup
11
- [x] open up a node and make current on startup
12
- [ ] find string
13
- [/] expand all descendants
14
- ++ +- and +?
15
- =end
16
- require 'rbcurse'
17
- require 'rbcurse/tree/treemodel'
18
- require 'rbcurse/tree/treecellrenderer'
19
-
20
- TreeSelectionEvent = Struct.new(:node, :tree, :state, :previous_node, :row_first)
21
-
22
- #include Ncurses # FFI 2011-09-8
23
- module RubyCurses
24
- extend self
25
- # a representation of heirarchical data in outline form
26
- # Currently supports only single selection, and does not allow editing.
27
- # @events Events: SELECT, DESELECT, TREE_WILL_EXPAND_EVENT, TREE_COLLAPSED_EVENT
28
- #
29
- class Tree < Widget
30
- require 'rbcurse/listscrollable'
31
- # currently just use single selection
32
- include ListScrollable
33
- #extend Forwardable
34
- dsl_accessor :height
35
- dsl_accessor :title
36
- dsl_property :title_attrib # bold, reverse, normal
37
- dsl_accessor :border_attrib, :border_color # FIXME not used currently
38
-
39
- attr_reader :toprow
40
- # attr_reader :prow
41
- # attr_reader :winrow
42
- dsl_accessor :default_value # node to show as selected - what if user doesn't have it?
43
- attr_accessor :current_index
44
- dsl_accessor :selected_color, :selected_bgcolor, :selected_attr
45
- dsl_accessor :max_visible_items # how many to display 2009-01-11 16:15
46
- dsl_accessor :cell_editing_allowed # obsolete
47
- dsl_accessor :suppress_borders
48
- dsl_property :show_selector
49
- dsl_property :row_selected_symbol # 2009-01-12 12:01 changed from selector to selected
50
- dsl_property :row_unselected_symbol # added 2009-01-12 12:00
51
- dsl_property :left_margin
52
- dsl_accessor :sanitization_required # 2011-10-6
53
- #dsl_accessor :valign # popup related
54
- #
55
- # will pressing a single key move to first matching row. setting it to false lets us use vim keys
56
- attr_accessor :one_key_selection # will pressing a single key move to first matching row
57
- # index of row selected, relates to internal representation, not tree. @see selected_row
58
- attr_reader :selected_index # index of row that is selected. this relates to representation
59
- attr_reader :treemodel # returns treemodel for further actions 2011-10-2
60
-
61
- def initialize form, config={}, &block
62
- @focusable = true
63
- @editable = false
64
- @row = 0
65
- @col = 0
66
- # array representation of tree
67
- @list = nil
68
- # any special attribs such as status to be printed in col1, or color (selection)
69
- @list_attribs = {}
70
- # hash containing nodes that are expanded or once expanded
71
- # if value is true, then currently expanded, else once expanded
72
- # TODO : will need purging under some situations
73
- @expanded_state = {}
74
- @suppress_borders = false
75
- @row_offset = @col_offset = 1
76
- @current_index = 0
77
- super
78
- #@selection_mode ||= :single # default is multiple, anything else given becomes single
79
- @win = @graphic # 2010-01-04 12:36 BUFFERED replace form.window with graphic
80
- @sanitization_required = true
81
- @longest_line = 0
82
-
83
-
84
- @win_left = 0
85
- @win_top = 0
86
- @_events.push(*[:ENTER_ROW, :LEAVE_ROW, :TREE_COLLAPSED_EVENT, :TREE_EXPANDED_EVENT, :TREE_SELECTION_EVENT, :TREE_WILL_COLLAPSE_EVENT, :TREE_WILL_EXPAND_EVENT])
87
-
88
-
89
- bind(:PROPERTY_CHANGE){|e| @cell_renderer = nil } # will be recreated if anything changes 2011-09-28 V1.3.1
90
- init_vars
91
-
92
- #if !@list.selected_index.nil?
93
- #set_focus_on @list.selected_index # the new version
94
- #end
95
- @keys_mapped = false
96
- end
97
- def init_vars
98
- @repaint_required = true
99
- @toprow = @pcol = 0
100
- if @show_selector
101
- @row_selected_symbol ||= '>'
102
- @row_unselected_symbol ||= ' '
103
- @left_margin ||= @row_selected_symbol.length
104
- end
105
- @left_margin ||= 0
106
- @one_key_selection = true if @one_key_selection.nil?
107
- @height ||= 10
108
- @width ||= 30
109
- @row_offset = @col_offset = 0 if @suppress_borders
110
- @internal_width = 2 # taking into account borders accounting for 2 cols
111
- @internal_width = 0 if @suppress_borders # should it be 0 ???
112
-
113
- end
114
- # maps keys to methods
115
- # checks @key_map can be :emacs or :vim.
116
- def map_keys
117
- @keys_mapped = true
118
- $log.debug " cam in XXXX map keys"
119
- bind_key(32){ toggle_row_selection() }
120
- bind_key(KEY_RETURN) { toggle_expanded_state() }
121
- bind_key(?o) { toggle_expanded_state() }
122
- bind_key(?f){ ask_selection_for_char() }
123
- bind_key(?\M-v){ @one_key_selection = !@one_key_selection }
124
- bind_key(KEY_DOWN){ next_row() }
125
- bind_key(KEY_UP){ previous_row() }
126
- bind_key(?O){ expand_children() }
127
- bind_key(?X){ collapse_children() }
128
- bind_key(?>, :scroll_right)
129
- bind_key(?<, :scroll_left)
130
- bind_key(?\M-l, :scroll_right)
131
- bind_key(?\M-h, :scroll_left)
132
- # TODO
133
- bind_key(?x){ collapse_parent() }
134
- bind_key(?p){ goto_parent() }
135
- if $key_map == :emacs
136
- $log.debug " EMACSam in XXXX map keys"
137
- bind_key(?\C-v){ scroll_forward }
138
- bind_key(?\M-v){ scroll_backward }
139
- bind_key(?\C-s){ ask_search() }
140
- bind_key(?\C-n){ next_row() }
141
- bind_key(?\C-p){ previous_row() }
142
- bind_key(?\M->){ goto_bottom() }
143
- bind_key(?\M-<){ goto_top() }
144
- else # :vim
145
- $log.debug " VIM cam in XXXX map keys"
146
- bind_key(?j){ next_row() }
147
- bind_key(?k){ previous_row() }
148
- bind_key(?\C-d){ scroll_forward }
149
- bind_key(?\C-b){ scroll_backward }
150
- bind_key(?G){ goto_bottom() }
151
- bind_key([?g,?g]){ goto_top() }
152
- bind_key(?/){ ask_search() }
153
- end
154
- end
155
-
156
- ##
157
- def row_count
158
- return 0 if @list.nil?
159
- @list.length
160
- end
161
- # at what row should scrolling begin
162
- def scrollatrow
163
- if @suppress_borders
164
- return @height - 1
165
- else
166
- return @height - 3
167
- end
168
- end
169
- #
170
- # Sets the given node as root and returns treemodel.
171
- # Returns root if no argument given.
172
- # Now we return root if already set
173
- # Made node nillable so we can return root.
174
- #
175
- # @raise ArgumentError if setting a root after its set
176
- # or passing nil if its not been set.
177
- def root node=nil, asks_allow_children=false, &block
178
- if @treemodel
179
- return @treemodel.root unless node
180
- raise ArgumentError, "Root already set"
181
- end
182
-
183
- raise ArgumentError, "root: node cannot be nil" unless node
184
- @treemodel = RubyCurses::DefaultTreeModel.new(node, asks_allow_children, &block)
185
- end
186
-
187
- # pass data to create this tree model
188
- # used to be list
189
- def data alist=nil
190
-
191
- # if nothing passed, print an empty root, rather than crashing
192
- alist = [] if alist.nil?
193
- @data = alist # data given by user
194
- case alist
195
- when Array
196
- @treemodel = RubyCurses::DefaultTreeModel.new("/")
197
- @treemodel.root.add alist
198
- when Hash
199
- @treemodel = RubyCurses::DefaultTreeModel.new("/")
200
- @treemodel.root.add alist
201
- when TreeNode
202
- # this is a root node
203
- @treemodel = RubyCurses::DefaultTreeModel.new(alist)
204
- when DefaultTreeModel
205
- @treemodel = alist
206
- else
207
- if alist.is_a? DefaultTreeModel
208
- @treemodel = alist
209
- else
210
- raise ArgumentError, "Tree does not know how to handle #{alist.class} "
211
- end
212
- end
213
- # we now have a tree
214
- raise "I still don't have a tree" unless @treemodel
215
- set_expanded_state(@treemodel.root, true)
216
- convert_to_list @treemodel
217
-
218
- # added on 2009-01-13 23:19 since updates are not automatic now
219
- #@list.bind(:LIST_DATA_EVENT) { |e| list_data_changed() }
220
- #create_default_list_selection_model TODO
221
- end
222
- # private, for use by repaint
223
- def _list
224
- if @_structure_changed
225
- @list = nil
226
- @_structure_changed = false
227
- end
228
- unless @list
229
- $log.debug " XXX recreating _list"
230
- convert_to_list @treemodel
231
- $log.debug " XXXX list: #{@list.size} : #{@list} "
232
- end
233
- return @list
234
- end
235
- def convert_to_list tree
236
- @list = get_expanded_descendants(tree.root)
237
- #$log.debug "XXX convert #{tree.root.children.size} "
238
- #$log.debug " converted tree to list. #{@list.size} "
239
- end
240
- def traverse node, level=0, &block
241
- raise "disuse"
242
- #icon = node.is_leaf? ? "-" : "+"
243
- #puts "%*s %s" % [ level+1, icon, node.user_object ]
244
- yield node, level if block_given?
245
- node.children.each do |e|
246
- traverse e, level+1, &block
247
- end
248
- end
249
- # return object under cursor
250
- # Note: this should not be confused with selected row/s. User may not have selected this.
251
- # This is only useful since in some demos we like to change a status bar as a user scrolls down
252
- # @since 1.2.0 2010-09-06 14:33 making life easier for others.
253
- def current_row
254
- @list[@current_index]
255
- end
256
- alias :text :current_row # thanks to shoes, not sure how this will impact since widget has text.
257
-
258
- # show default value as selected and fire handler for it
259
- # This is called in repaint, so can raise an error if called on creation
260
- # or before repaint. Just set @default_value, and let us handle the rest.
261
- # Suggestions are welcome.
262
- def select_default_values
263
- return if @default_value.nil?
264
- # NOTE list not yet created
265
- raise "list has not yet been created" unless @list
266
- index = node_to_row @default_value
267
- raise "could not find node #{@default_value}, #{@list} " unless index
268
- return unless index
269
- @current_index = index
270
- toggle_row_selection
271
- @default_value = nil
272
- end
273
- def print_borders
274
- width = @width
275
- height = @height-1 # 2010-01-04 15:30 BUFFERED HEIGHT
276
- window = @graphic # 2010-01-04 12:37 BUFFERED
277
- startcol = @col
278
- startrow = @row
279
- @color_pair = get_color($datacolor)
280
- # bordercolor = @border_color || $datacolor # changed 2011 dts
281
- bordercolor = @border_color || @color_pair # 2011-09-28 V1.3.1
282
- borderatt = @border_attrib || Ncurses::A_NORMAL
283
-
284
- window.print_border startrow, startcol, height, width, bordercolor, borderatt
285
- print_title
286
- end
287
- def print_title
288
- return unless @title
289
- _title = @title
290
- if @title.length > @width - 2
291
- _title = @title[0..@width-2]
292
- end
293
- @color_pair ||= get_color($datacolor)
294
- @graphic.printstring( @row, @col+(@width-_title.length)/2, _title, @color_pair, @title_attrib) unless @title.nil?
295
- end
296
- ### START FOR scrollable ###
297
- def get_content
298
- #@list 2008-12-01 23:13
299
- @list_variable && @list_variable.value || @list
300
- # called by next_match in listscrollable
301
- @list
302
- end
303
- def get_window
304
- @graphic # 2010-01-04 12:37 BUFFERED
305
- end
306
- ### END FOR scrollable ###
307
- # override widgets text
308
- def getvalue
309
- selected_row()
310
- end
311
- # Listbox
312
- def handle_key(ch)
313
- return if @list.nil? || @list.empty?
314
- @current_index ||= 0
315
- @toprow ||= 0
316
- map_keys unless @keys_mapped
317
- h = scrollatrow()
318
- rc = row_count
319
- $log.debug " tree got ch #{ch}"
320
- case ch
321
- when 27, ?\C-c.getbyte(0)
322
- #editing_canceled @current_index if @cell_editing_allowed
323
- #cancel_block # block
324
- $multiplier = 0
325
- return 0
326
- #when ?\C-u.getbyte(0)
327
- # multiplier. Series is 4 16 64
328
- # TESTING @multiplier = (@multiplier == 0 ? 4 : @multiplier *= 4)
329
- # return 0
330
- when ?\C-c.getbyte(0)
331
- @multiplier = 0
332
- return 0
333
- else
334
- ret = :UNHANDLED
335
- if ret == :UNHANDLED
336
- # beware one-key eats up numbers. we'll be wondering why
337
- if @one_key_selection
338
- case ch
339
- #when ?A.getbyte(0)..?Z.getbyte(0), ?a.getbyte(0)..?z.getbyte(0), ?0.getbyte(0)..?9.getbyte(0)
340
- when ?A.getbyte(0)..?Z.getbyte(0), ?a.getbyte(0)..?z.getbyte(0)
341
- # simple motion, key press defines motion
342
- ret = set_selection_for_char ch.chr
343
- else
344
- ret = process_key ch, self
345
- @multiplier = 0
346
- return :UNHANDLED if ret == :UNHANDLED
347
- end
348
- else
349
- # no motion on single key, we can freak out like in vim, pref f <char> for set_selection
350
- case ch
351
- when ?0.getbyte(0)..?9.getbyte(0)
352
- $multiplier *= 10 ; $multiplier += (ch-48)
353
- #$log.debug " setting mult to #{$multiplier} in list "
354
- return 0
355
- end
356
- $log.debug " TREE before process key #{ch} "
357
- ret = process_key ch, self
358
- $log.debug " TREE after process key #{ch} #{ret} "
359
- #$multiplier = 0 # 2010-09-02 22:35 this prevents parent from using mult
360
- return :UNHANDLED if ret == :UNHANDLED
361
- end
362
- end
363
- end
364
- $multiplier = 0
365
- end
366
- # get a keystroke from user and go to first item starting with that key
367
- def ask_selection_for_char
368
- ch = @graphic.getch
369
- if ch < 0 || ch > 255
370
- return :UNHANDLED
371
- end
372
- ret = set_selection_for_char ch.chr
373
- end
374
- def ask_search_forward
375
- regex = get_string("Enter regex to search")
376
- ix = @list.find_match regex
377
- if ix.nil?
378
- alert("No matching data for: #{regex}")
379
- else
380
- set_focus_on(ix)
381
- end
382
- end
383
- # gets string to search and calls data models find prev
384
- def ask_search_backward
385
- regex = get_string("Enter regex to search (backward)")
386
- @last_regex = regex
387
- ix = @list.find_prev regex, @current_index
388
- if ix.nil?
389
- alert("No matching data for: #{regex}")
390
- else
391
- set_focus_on(ix)
392
- end
393
- end
394
- # please check for error before proceeding
395
- # @return [Boolean] false if no data
396
- def on_enter
397
- if @list.size < 1
398
- Ncurses.beep
399
- return false
400
- end
401
- on_enter_row @current_index
402
- set_form_row # added 2009-01-11 23:41
403
- #$log.debug " ONE ENTER LIST #{@current_index}, #{@form.row}"
404
- @repaint_required = true
405
- super
406
- #fire_handler :ENTER, self
407
- true
408
- end
409
- def on_enter_row arow
410
- #$log.debug " Listbox #{self} ENTER_ROW with curr #{@current_index}. row: #{arow} H: #{@handler.keys}"
411
- #fire_handler :ENTER_ROW, arow
412
- fire_handler :ENTER_ROW, self
413
- #@list.on_enter_row self TODO
414
- #edit_row_at arow
415
- @repaint_required = true
416
- end
417
- ##
418
- def on_leave_row arow
419
- #$log.debug " Listbox #{self} leave with (cr: #{@current_index}) #{arow}: list[row]:#{@list[arow]}"
420
- #$log.debug " Listbox #{self} leave with (cr: #{@current_index}) #{arow}: "
421
- #fire_handler :LEAVE_ROW, arow
422
- fire_handler :LEAVE_ROW, self
423
- #editing_completed arow
424
- end
425
-
426
- ##
427
- # getter and setter for cell_renderer
428
- def cell_renderer(*val)
429
- if val.empty?
430
- @cell_renderer ||= create_default_cell_renderer
431
- else
432
- @cell_renderer = val[0]
433
- end
434
- end
435
- def create_default_cell_renderer
436
- return RubyCurses::TreeCellRenderer.new "", {"color"=>@color, "bgcolor"=>@bgcolor, "parent" => self, "display_length"=> @width-@internal_width-@left_margin}
437
- end
438
- ##
439
- # this method chops the data to length before giving it to the
440
- # renderer, this can cause problems if the renderer does some
441
- # processing. also, it pans the data horizontally giving the renderer
442
- # a section of it.
443
- # FIXME: tree may not be clearing till end see appdirtree after divider movement
444
- def repaint
445
- return unless @repaint_required
446
-
447
- my_win = @form ? @form.window : @target_window
448
- @graphic = my_win unless @graphic
449
-
450
- raise " #{@name} neither form, nor target window given TV paint " unless my_win
451
- raise " #{@name} NO GRAPHIC set as yet TV paint " unless @graphic
452
- @win_left = my_win.left
453
- @win_top = my_win.top
454
-
455
- $log.debug "rtree repaint #{@name} graphic #{@graphic}"
456
- print_borders unless @suppress_borders # do this once only, unless everything changes
457
- maxlen = @maxlen || @width-@internal_width
458
- maxlen -= @left_margin # 2011-10-6
459
- tm = _list()
460
- select_default_values
461
- rc = row_count
462
- tr = @toprow
463
- acolor = get_color $datacolor
464
- h = scrollatrow()
465
- r,c = rowcol
466
- @longest_line = @width #maxlen
467
- 0.upto(h) do |hh|
468
- crow = tr+hh
469
- if crow < rc
470
- _focussed = @current_index == crow ? true : false # row focussed ?
471
- focus_type = _focussed
472
- # added 2010-09-02 14:39 so inactive fields don't show a bright focussed line
473
- #focussed = false if focussed && !@focussed
474
- focus_type = :SOFT_FOCUS if _focussed && !@focussed
475
- selected = row_selected? crow
476
- content = tm[crow] # 2009-01-17 18:37 chomp giving error in some cases says frozen
477
- if content.is_a? TreeNode
478
- node = content
479
- object = content
480
- leaf = node.is_leaf?
481
- # content passed is rejected by treecellrenderer 2011-10-6
482
- content = node.user_object.to_s # may need to trim or truncate
483
- expanded = row_expanded? crow
484
- elsif content.is_a? String
485
- $log.warn "Removed this entire block since i don't think it was used XXX "
486
- # this block does not set object XXX
487
- else
488
- raise "repaint what is the class #{content.class} "
489
- content = content.to_s
490
- end
491
- # this is redundant since data is taken by renderer directly
492
- #sanitize content if @sanitization_required
493
- #truncate value
494
- ## set the selector symbol if requested
495
- selection_symbol = ''
496
- if @show_selector
497
- if selected
498
- selection_symbol = @row_selected_symbol
499
- else
500
- selection_symbol = @row_unselected_symbol
501
- end
502
- @graphic.printstring r+hh, c, selection_symbol, acolor,@attr
503
- end
504
-
505
- renderer = cell_renderer()
506
- renderer.display_length(@width-@internal_width-@left_margin) # just in case resizing of listbox
507
- renderer.pcol = @pcol
508
- #renderer.repaint @graphic, r+hh, c+@left_margin, crow, content, _focussed, selected
509
- renderer.repaint @graphic, r+hh, c+@left_margin, crow, object, content, leaf, focus_type, selected, expanded
510
- @longest_line = renderer.actual_length if renderer.actual_length > @longest_line
511
- else
512
- # clear rows
513
- @graphic.printstring r+hh, c, " " * (@width-@internal_width), acolor,@attr
514
- end
515
- end
516
- @table_changed = false
517
- @repaint_required = false
518
- end
519
-
520
- def list_data_changed
521
- if row_count == 0 # added on 2009-02-02 17:13 so cursor not hanging on last row which could be empty
522
- init_vars
523
- @current_index = 0
524
- set_form_row
525
- end
526
- @repaint_required = true
527
- end
528
- def set_form_col col1=0
529
- @cols_panned ||= 0 # RFED16 2010-02-17 23:40
530
- win_col = 0
531
- col2 = win_col + @col + @col_offset + col1 + @cols_panned + @left_margin
532
- setrowcol nil, col2 # 2010-02-17 23:19 RFED16
533
- end
534
- def selected_row
535
- @list[@selected_index].node
536
- end
537
-
538
- # An event is thrown when a row is selected or deselected.
539
- # Please note that when a row is selected, another one is automatically deselected.
540
- # An event is not thrown for that since your may not want to collapse that.
541
- # Only clicking on a selected row, will send a DESELECT on it since you may want to collapse it.
542
- # However, the previous selection is also present in the event object, so you can act upon it.
543
- # This is not used for expanding or collapsing, only for application to show some data in another
544
- # window or pane based on selection. Maybe there should not be a deselect for current row ?
545
- def toggle_row_selection
546
- node = @list[@current_index]
547
- previous_node = nil
548
- previous_node = @list[@selected_index] if @selected_index
549
- if @selected_index == @current_index
550
- @selected_index = nil
551
- else
552
- @selected_index = @current_index
553
- end
554
- state = @selected_index.nil? ? :DESELECTED : :SELECTED
555
- #TreeSelectionEvent = Struct.new(:node, :tree, :state, :previous_node, :row_first)
556
- @tree_selection_event = TreeSelectionEvent.new(node, self, state, previous_node, @current_index) #if @item_event.nil?
557
- fire_handler :TREE_SELECTION_EVENT, @tree_selection_event # should the event itself be ITEM_EVENT
558
- $log.debug " XXX tree selected #{@selected_index}/ #{@current_index} , #{state} "
559
- @repaint_required = true
560
- end
561
- def toggle_expanded_state row=@current_index
562
- state = row_expanded? row
563
- node = row_to_node
564
- if node.nil?
565
- Ncurses.beep
566
- $log.debug " No such node on row #{row} "
567
- return
568
- end
569
- $log.debug " toggle XXX state #{state} #{node} "
570
- if state
571
- collapse_node node
572
- else
573
- expand_node node
574
- end
575
- end
576
- def row_to_node row=@current_index
577
- @list[row]
578
- end
579
- # convert a given node to row
580
- def node_to_row node
581
- crow = nil
582
- @list.each_with_index { |e,i|
583
- if e == node
584
- crow = i
585
- break
586
- end
587
- }
588
- crow
589
- end
590
- # private
591
- # related to index in representation, not tree
592
- def row_selected? row
593
- @selected_index == row
594
- end
595
- # @return [TreeNode, nil] returns selected node or nil
596
-
597
- def row_expanded? row
598
- node = @list[row]
599
- node_expanded? node
600
- end
601
- def row_collapsed? row
602
- !row_expanded? row
603
- end
604
- def set_expanded_state(node, state)
605
- @expanded_state[node] = state
606
- @repaint_required = true
607
- _structure_changed true
608
- end
609
- def expand_node(node)
610
- #$log.debug " expand called on #{node.user_object} "
611
- state = true
612
- fire_handler :TREE_WILL_EXPAND_EVENT, node
613
- set_expanded_state(node, state)
614
- fire_handler :TREE_EXPANDED_EVENT, node
615
- end
616
- def collapse_node(node)
617
- $log.debug " collapse called on #{node.user_object} "
618
- state = false
619
- fire_handler :TREE_WILL_COLLAPSE_EVENT, node
620
- set_expanded_state(node, state)
621
- fire_handler :TREE_COLLAPSED_EVENT, node
622
- end
623
- # this is required to make a node visible, if you wish to start from a node that is not root
624
- # e.g. you are loading app in a dir somewhere but want to show path from root down.
625
- # NOTE this sucks since you have to click 2 times to expand it.
626
- def mark_parents_expanded node
627
- # i am setting parents as expanded, but NOT firing handlers - XXX separate this into expand_parents
628
- _path = node.tree_path
629
- _path.each do |e|
630
- # if already expanded parent then break we should break
631
- set_expanded_state(e, true)
632
- end
633
- end
634
- # goes up to root of this node, and expands down to this node
635
- # this is often required to make a specific node visible such
636
- # as in a dir listing when current dir is deep in heirarchy.
637
- def expand_parents node
638
- _path = node.tree_path
639
- _path.each do |e|
640
- # if already expanded parent then break we should break
641
- #set_expanded_state(e, true)
642
- expand_node(e)
643
- end
644
- end
645
- # this expands all the children of a node, recursively
646
- # we can't use multiplier concept here since we are doing a preorder enumeration
647
- # we need to do a breadth first enumeration to use a multiplier
648
- #
649
- def expand_children node=:current_index
650
- $multiplier = 999 if !$multiplier || $multiplier == 0
651
- node = row_to_node if node == :current_index
652
- return if node.children.empty? # or node.is_leaf?
653
- #node.children.each do |e|
654
- #expand_node e # this will keep expanding parents
655
- #expand_children e
656
- #end
657
- node.breadth_each($multiplier) do |e|
658
- expand_node e
659
- end
660
- $multiplier = 0
661
- _structure_changed true
662
- end
663
- def collapse_children node=:current_index
664
- $multiplier = 999 if !$multiplier || $multiplier == 0
665
- $log.debug " CCCC IINSIDE COLLLAPSE"
666
- node = row_to_node if node == :current_index
667
- return if node.children.empty? # or node.is_leaf?
668
- #node.children.each do |e|
669
- #expand_node e # this will keep expanding parents
670
- #expand_children e
671
- #end
672
- node.breadth_each($multiplier) do |e|
673
- $log.debug "CCC collapsing #{e.user_object} "
674
- collapse_node e
675
- end
676
- $multiplier = 0
677
- _structure_changed true
678
- end
679
- # collapse parent
680
- # can use multiplier.
681
- # # we need to move up also
682
- def collapse_parent node=:current_index
683
- node = row_to_node if node == :current_index
684
- parent = node.parent
685
- return if parent.nil?
686
- goto_parent node
687
- collapse_node parent
688
- end
689
- def goto_parent node=:current_index
690
- node = row_to_node if node == :current_index
691
- parent = node.parent
692
- return if parent.nil?
693
- crow = @current_index
694
- @list.each_with_index { |e,i|
695
- if e == parent
696
- crow = i
697
- break
698
- end
699
- }
700
- @repaint_required = true
701
- #set_form_row # will not work if off form
702
- set_focus_on crow
703
- end
704
-
705
- def has_been_expanded node
706
- @expanded_state.has_key? node
707
- end
708
- def node_expanded? node
709
- @expanded_state[node] == true
710
- end
711
- def node_collapsed? node
712
- !node_expanded?(node)
713
- end
714
- def get_expanded_descendants(node)
715
- nodes = []
716
- nodes << node
717
- traverse_expanded node, nodes
718
- $log.debug " def get_expanded_descendants(node) #{nodes.size} "
719
- return nodes
720
- end
721
- def traverse_expanded node, nodes
722
- return if !node_expanded? node
723
- #nodes << node
724
- node.children.each do |e|
725
- nodes << e
726
- if node_expanded? e
727
- traverse_expanded e, nodes
728
- else
729
- next
730
- end
731
- end
732
- end
733
-
734
- #
735
- # To retrieve the node corresponding to a path specified as an array or string
736
- # Do not mention the root.
737
- # e.g. "ruby/1.9.2/io/console"
738
- # or %w[ ruby 1.9.3 io console ]
739
- # @since 1.4.0 2011-10-2
740
- def get_node_for_path(user_path)
741
- case user_path
742
- when String
743
- user_path = user_path.split "/"
744
- when Array
745
- else
746
- raise ArgumentError, "Should be Array or String delimited with /"
747
- end
748
- $log.debug "TREE #{user_path} " if $log.debug?
749
- root = @treemodel.root
750
- found = nil
751
- user_path.each { |e|
752
- success = false
753
- root.children.each { |c|
754
- if c.user_object == e
755
- found = c
756
- success = true
757
- root = c
758
- break
759
- end
760
- }
761
- return false unless success
762
-
763
- }
764
- return found
765
- end
766
- private
767
- # please do not rely on this yet, name could change
768
- def _structure_changed tf=true
769
- @_structure_changed = tf
770
- @repaint_required = true
771
- #@list = nil
772
- end
773
-
774
-
775
-
776
- # ADD HERE
777
- end # class tree
778
-
779
-
780
- end # module