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.
- data/CHANGELOG +31 -0
- data/README.markdown +69 -11
- data/VERSION +1 -1
- data/lib/rbcurse.rb +5 -5
- metadata +10 -198
- data/Makefile +0 -21
- data/Manifest.txt +0 -91
- data/TODO +0 -372
- data/TODO2.txt +0 -118
- data/examples/README.txt +0 -67
- data/examples/abasiclist.rb +0 -33
- data/examples/alpmenu.rb +0 -42
- data/examples/app.rb +0 -859
- data/examples/app.sample +0 -10
- data/examples/appdirtree.rb +0 -75
- data/examples/appemail.rb +0 -191
- data/examples/appemaillb.rb +0 -308
- data/examples/appgcompose.rb +0 -315
- data/examples/atree.rb +0 -64
- data/examples/common/file.rb +0 -40
- data/examples/common/rmail.rb +0 -257
- data/examples/data.txt +0 -683
- data/examples/data/README.markdown +0 -9
- data/examples/data/brew.txt +0 -38
- data/examples/data/color.2 +0 -37
- data/examples/data/gemlist.txt +0 -60
- data/examples/data/lotr.txt +0 -12
- data/examples/data/ports.txt +0 -136
- data/examples/data/tasks.txt +0 -27
- data/examples/data/todocsv.csv +0 -28
- data/examples/data/unix1.txt +0 -21
- data/examples/data/unix2.txt +0 -11
- data/examples/dbdemo.rb +0 -495
- data/examples/deprecated/appgmail.rb +0 -952
- data/examples/deprecated/splitp.rb +0 -56
- data/examples/deprecated/testscrolllb.rb +0 -86
- data/examples/deprecated/testscrollp.rb +0 -88
- data/examples/deprecated/testscrollta.rb +0 -80
- data/examples/deprecated/testscrolltable.rb +0 -165
- data/examples/deprecated/testsplit.rb +0 -87
- data/examples/deprecated/testsplit2.rb +0 -123
- data/examples/deprecated/testsplit3.rb +0 -215
- data/examples/deprecated/testsplit3_1.rb +0 -244
- data/examples/deprecated/testsplit3a.rb +0 -215
- data/examples/deprecated/testsplit3b.rb +0 -237
- data/examples/deprecated/testsplitta.rb +0 -148
- data/examples/deprecated/testsplittv.rb +0 -142
- data/examples/deprecated/testsplittvv.rb +0 -144
- data/examples/deprecated/testtpane.rb +0 -215
- data/examples/deprecated/testtpane2.rb +0 -145
- data/examples/deprecated/testtpanetable.rb +0 -203
- data/examples/dirtree.rb +0 -88
- data/examples/experimental/resultsetdemo.rb +0 -280
- data/examples/experimental/testmform.rb +0 -35
- data/examples/experimental/testscroller.rb +0 -117
- data/examples/experimental/teststackflow.rb +0 -111
- data/examples/menu1.rb +0 -112
- data/examples/multispl.rb +0 -86
- data/examples/newmessagebox.rb +0 -130
- data/examples/newtabbedwindow.rb +0 -100
- data/examples/newtesttabp.rb +0 -121
- data/examples/qdfilechooser.rb +0 -68
- data/examples/rfe.rb +0 -1195
- data/examples/rfe_renderer.rb +0 -121
- data/examples/sqlc.rb +0 -454
- data/examples/sqlm.rb +0 -437
- data/examples/sqlt.rb +0 -408
- data/examples/status.txt +0 -68
- data/examples/table1.rb +0 -24
- data/examples/term2.rb +0 -84
- data/examples/test1.rb +0 -239
- data/examples/test2.rb +0 -674
- data/examples/testapp.rb +0 -44
- data/examples/testapp2.rb +0 -58
- data/examples/testchars.rb +0 -137
- data/examples/testcombo.rb +0 -91
- data/examples/testkeypress.rb +0 -66
- data/examples/testlistbox.rb +0 -113
- data/examples/testmenu.rb +0 -101
- data/examples/testmulticomp.rb +0 -70
- data/examples/testmulticontainer.rb +0 -94
- data/examples/testmultispl.rb +0 -199
- data/examples/testree.rb +0 -106
- data/examples/testtable.rb +0 -263
- data/examples/testtabp.rb +0 -107
- data/examples/testtodo.rb +0 -584
- data/examples/testvimsplit.rb +0 -112
- data/examples/testwsshortcuts.rb +0 -64
- data/examples/testwsshortcuts2.rb +0 -126
- data/examples/todo.db +0 -0
- data/examples/todo.yml +0 -191
- data/examples/viewtodo.rb +0 -574
- data/lib/rbcurse/action.rb +0 -40
- data/lib/rbcurse/app.rb +0 -1374
- data/lib/rbcurse/applicationheader.rb +0 -102
- data/lib/rbcurse/celleditor.rb +0 -112
- data/lib/rbcurse/checkboxcellrenderer.rb +0 -57
- data/lib/rbcurse/colormap.rb +0 -159
- data/lib/rbcurse/comboboxcellrenderer.rb +0 -30
- data/lib/rbcurse/common/ansiparser.rb +0 -117
- data/lib/rbcurse/common/appmethods.rb +0 -112
- data/lib/rbcurse/common/basestack.rb +0 -407
- data/lib/rbcurse/common/bordertitle.rb +0 -41
- data/lib/rbcurse/common/chunk.rb +0 -177
- data/lib/rbcurse/common/colorparser.rb +0 -71
- data/lib/rbcurse/common/keydefs.rb +0 -30
- data/lib/rbcurse/common/widgetshortcuts.rb +0 -302
- data/lib/rbcurse/defaultlistselectionmodel.rb +0 -79
- data/lib/rbcurse/deprecated/README.markdown +0 -12
- data/lib/rbcurse/deprecated/rscrollpane.rb +0 -512
- data/lib/rbcurse/deprecated/rsplitpane.rb +0 -894
- data/lib/rbcurse/deprecated/rsplitpane2.rb +0 -1009
- data/lib/rbcurse/deprecated/rviewport.rb +0 -204
- data/lib/rbcurse/experimental/README.markdown +0 -14
- data/lib/rbcurse/experimental/resultsettextview.rb +0 -585
- data/lib/rbcurse/experimental/stackflow.rb +0 -478
- data/lib/rbcurse/extras/bottomline.rb +0 -1850
- data/lib/rbcurse/extras/box.rb +0 -58
- data/lib/rbcurse/extras/directorylist.rb +0 -467
- data/lib/rbcurse/extras/directorytree.rb +0 -69
- data/lib/rbcurse/extras/divider.rb +0 -310
- data/lib/rbcurse/extras/focusmanager.rb +0 -31
- data/lib/rbcurse/extras/horizlist.rb +0 -203
- data/lib/rbcurse/extras/listselectable.rb +0 -264
- data/lib/rbcurse/extras/masterdetail.rb +0 -166
- data/lib/rbcurse/extras/menutree.rb +0 -63
- data/lib/rbcurse/extras/multiform.rb +0 -330
- data/lib/rbcurse/extras/multilinelabel.rb +0 -142
- data/lib/rbcurse/extras/newmessagebox.rb +0 -328
- data/lib/rbcurse/extras/newtabbedpane.rb +0 -612
- data/lib/rbcurse/extras/newtabbedwindow.rb +0 -68
- data/lib/rbcurse/extras/padreader.rb +0 -189
- data/lib/rbcurse/extras/rcomboedit.rb +0 -256
- data/lib/rbcurse/extras/resultsetbrowser.rb +0 -281
- data/lib/rbcurse/extras/rlink.rb +0 -27
- data/lib/rbcurse/extras/rmenulink.rb +0 -21
- data/lib/rbcurse/extras/scrollbar.rb +0 -143
- data/lib/rbcurse/extras/statusline.rb +0 -94
- data/lib/rbcurse/extras/stdscrwindow.rb +0 -309
- data/lib/rbcurse/extras/tableextended.rb +0 -40
- data/lib/rbcurse/extras/tabular.rb +0 -264
- data/lib/rbcurse/extras/tabularwidget.rb +0 -1150
- data/lib/rbcurse/extras/textpad.rb +0 -516
- data/lib/rbcurse/extras/viewer.rb +0 -136
- data/lib/rbcurse/io.rb +0 -850
- data/lib/rbcurse/keylabelprinter.rb +0 -178
- data/lib/rbcurse/listcellrenderer.rb +0 -140
- data/lib/rbcurse/listeditable.rb +0 -310
- data/lib/rbcurse/listkeys.rb +0 -37
- data/lib/rbcurse/listscrollable.rb +0 -564
- data/lib/rbcurse/listselectable.rb +0 -142
- data/lib/rbcurse/mapper.rb +0 -130
- data/lib/rbcurse/orderedhash.rb +0 -77
- data/lib/rbcurse/ractionevent.rb +0 -67
- data/lib/rbcurse/rbasiclistbox.rb +0 -768
- data/lib/rbcurse/rchangeevent.rb +0 -27
- data/lib/rbcurse/rcombo.rb +0 -238
- data/lib/rbcurse/rcommandwindow.rb +0 -587
- data/lib/rbcurse/rcontainer.rb +0 -415
- data/lib/rbcurse/rdialogs.rb +0 -451
- data/lib/rbcurse/rinputdataevent.rb +0 -47
- data/lib/rbcurse/rlistbox.rb +0 -1196
- data/lib/rbcurse/rmenu.rb +0 -939
- data/lib/rbcurse/rmessagebox.rb +0 -348
- data/lib/rbcurse/rmulticontainer.rb +0 -304
- data/lib/rbcurse/rmultisplit.rb +0 -722
- data/lib/rbcurse/rmultitextview.rb +0 -306
- data/lib/rbcurse/rpopupmenu.rb +0 -755
- data/lib/rbcurse/rprogress.rb +0 -118
- data/lib/rbcurse/rscrollform.rb +0 -418
- data/lib/rbcurse/rtabbedpane.rb +0 -1158
- data/lib/rbcurse/rtabbedwindow.rb +0 -167
- data/lib/rbcurse/rtable.rb +0 -1718
- data/lib/rbcurse/rtextarea.rb +0 -920
- data/lib/rbcurse/rtextview.rb +0 -761
- data/lib/rbcurse/rtree.rb +0 -780
- data/lib/rbcurse/rvimsplit.rb +0 -763
- data/lib/rbcurse/rwidget.rb +0 -2915
- data/lib/rbcurse/scrollable.rb +0 -301
- data/lib/rbcurse/table/tablecellrenderer.rb +0 -86
- data/lib/rbcurse/table/tabledatecellrenderer.rb +0 -98
- data/lib/rbcurse/tree/treecellrenderer.rb +0 -150
- data/lib/rbcurse/tree/treemodel.rb +0 -428
- data/lib/rbcurse/undomanager.rb +0 -188
- data/lib/rbcurse/vieditable.rb +0 -144
- data/lib/ver/keyboard.rb +0 -150
- data/lib/ver/keyboard2.rb +0 -170
- data/lib/ver/ncurses.rb +0 -218
- data/lib/ver/panel.rb +0 -162
- data/lib/ver/rpad.rb +0 -375
- data/lib/ver/window.rb +0 -882
- data/test/test_rbcurse.rb +0 -0
@@ -1,1150 +0,0 @@
|
|
1
|
-
=begin
|
2
|
-
* Name: TabularWidget
|
3
|
-
* Description A widget based on Tabular
|
4
|
-
* Author: rk (arunachalesha)
|
5
|
-
* file created 2010-09-28 23:37
|
6
|
-
FIXME:
|
7
|
-
|
8
|
-
TODO
|
9
|
-
* guess_c : have some config : NEVER, FIRST_TIME, EACH_TIME
|
10
|
-
if user has specified widths then we don't wanna guess. guess_size 20, ALL.
|
11
|
-
* move columns
|
12
|
-
* hide columns - importnat since with sorting we may need to store an identifier which
|
13
|
-
should not be displayed
|
14
|
-
x data truncation based on col wid TODO
|
15
|
-
* TODO: search -- how is it working, but curpos is wrong.
|
16
|
-
* allow resize of column inside column header
|
17
|
-
* Now that we allow header to get focus, we should allow it to handle
|
18
|
-
keys, but its not an object like it was in rtable ! AARGH !
|
19
|
-
* NOTE: header could become an object in near future, but then why did we break
|
20
|
-
away from rtable ?
|
21
|
-
* TODO FIXME : after converting to convert_value_to_text and truncation etc, numbering is broken
|
22
|
-
* we are checking widths of columsn and we have added a column, so columns widths refer to wrong col
|
23
|
-
TODO : tabbing with w to take care of hidden columns and numbering. FIXME
|
24
|
-
TODO: we forgot about selection altogether. we need multiple select !!! as in gmail
|
25
|
-
subject list.
|
26
|
-
--------
|
27
|
-
* License:
|
28
|
-
Same as Ruby's License (http://www.ruby-lang.org/LICENSE.txt)
|
29
|
-
|
30
|
-
=end
|
31
|
-
require 'rbcurse'
|
32
|
-
require 'rbcurse/listscrollable'
|
33
|
-
require 'rbcurse/extras/tabular'
|
34
|
-
require 'rbcurse/extras/listselectable'
|
35
|
-
|
36
|
-
#include RubyCurses
|
37
|
-
module RubyCurses
|
38
|
-
extend self
|
39
|
-
# used when firing a column resize, so calling application can perhaps
|
40
|
-
# resize other columns.
|
41
|
-
class ColumnResizeEvent < Struct.new(:source, :index, :type); end
|
42
|
-
|
43
|
-
##
|
44
|
-
# A viewable read only, scrollable table. This is supposed to be a
|
45
|
-
# +minimal+, and (hopefully) fast version of Table (@see rtable.rb).
|
46
|
-
class TabularWidget < Widget
|
47
|
-
|
48
|
-
|
49
|
-
include ListScrollable
|
50
|
-
include NewListSelectable
|
51
|
-
dsl_accessor :title # set this on top
|
52
|
-
dsl_accessor :title_attrib # bold, reverse, normal
|
53
|
-
dsl_accessor :footer_attrib # bold, reverse, normal
|
54
|
-
dsl_accessor :list # the array of arrays of data to be sent by user XXX RISKY bypasses set_content
|
55
|
-
dsl_accessor :maxlen # max len to be displayed
|
56
|
-
attr_reader :toprow # the toprow in the view (offsets are 0)
|
57
|
-
attr_reader :winrow # the row in the viewport/window
|
58
|
-
# painting the footer does slow down cursor painting slightly if one is moving cursor fast
|
59
|
-
dsl_accessor :print_footer
|
60
|
-
dsl_accessor :suppress_borders
|
61
|
-
attr_accessor :current_index
|
62
|
-
dsl_accessor :border_attrib, :border_color # color pair for border
|
63
|
-
dsl_accessor :header_attrib, :header_fgcolor, :header_bgcolor # 2010-10-15 13:21
|
64
|
-
|
65
|
-
# boolean, whether lines should be cleaned (if containing tabs/newlines etc)
|
66
|
-
dsl_accessor :sanitization_required
|
67
|
-
# boolean, whether column widths should be estimated based on data. If you want this,
|
68
|
-
# set to true each time you do a set_content
|
69
|
-
dsl_accessor :estimate_column_widths
|
70
|
-
# boolean, whether lines should be numbered
|
71
|
-
attr_accessor :numbering
|
72
|
-
# default or custom sorter
|
73
|
-
attr_reader :table_row_sorter
|
74
|
-
|
75
|
-
# @group select related
|
76
|
-
dsl_accessor :selection_mode
|
77
|
-
dsl_accessor :selected_color, :selected_bgcolor, :selected_attr
|
78
|
-
|
79
|
-
dsl_property :show_selector # boolean
|
80
|
-
dsl_property :row_selected_symbol
|
81
|
-
dsl_property :row_unselected_symbol
|
82
|
-
attr_accessor :selected_index # should we use only indices ??
|
83
|
-
# index of selected rows, if multiple selection asked for
|
84
|
-
attr_reader :selected_indices
|
85
|
-
attr_reader :_header_adjustment # we need to adjust when using current_index !!! UGH
|
86
|
-
# @endgroup select related
|
87
|
-
|
88
|
-
def initialize form = nil, config={}, &block
|
89
|
-
@focusable = true
|
90
|
-
@editable = false
|
91
|
-
@sanitization_required = true
|
92
|
-
@estimate_column_widths = true
|
93
|
-
@row = 0
|
94
|
-
@col = 0
|
95
|
-
@cw = {} # column widths keyed on column index - why not array ??
|
96
|
-
@pw = [] # preferred column widths 2010-10-20 12:58
|
97
|
-
@calign = {} # columns aligns values, on column index
|
98
|
-
@coffsets = {}
|
99
|
-
@suppress_borders = false
|
100
|
-
@row_offset = @col_offset = 1
|
101
|
-
@chash = {}
|
102
|
-
# this should have index of displayed column
|
103
|
-
# so user can reorder columns
|
104
|
-
#@column_position = [] # TODO
|
105
|
-
@separ = @columns = @numbering = nil
|
106
|
-
@y = '|'
|
107
|
-
@x = '+'
|
108
|
-
@list = []
|
109
|
-
@_header_adjustment = 0
|
110
|
-
@show_focus = false # don't highlight row under focus TODO
|
111
|
-
@selection_mode = :multiple # default is multiple, anything else given becomes single
|
112
|
-
@row_selected_symbol = '*'
|
113
|
-
@show_selector = true
|
114
|
-
super
|
115
|
-
# ideally this should have been 2 to take care of borders, but that would break
|
116
|
-
# too much stuff !
|
117
|
-
@win = @graphic
|
118
|
-
|
119
|
-
@_events.push :CHANGE # thru vieditable
|
120
|
-
@_events << :PRESS # new, in case we want to use this for lists and allow ENTER
|
121
|
-
@_events << :ENTER_ROW # new, should be there in listscrollable ??
|
122
|
-
@_events << :COLUMN_RESIZE_EVENT
|
123
|
-
install_keys # << almost jnuk now, clean off TODO
|
124
|
-
init_vars
|
125
|
-
map_keys
|
126
|
-
end
|
127
|
-
def init_vars #:nodoc:
|
128
|
-
@curpos = @pcol = @toprow = @current_index = 0
|
129
|
-
@repaint_all=true
|
130
|
-
@repaint_required=true
|
131
|
-
|
132
|
-
@row_offset = @col_offset = 0 if @suppress_borders == true
|
133
|
-
@internal_width = 2
|
134
|
-
@internal_width = 0 if @suppress_borders
|
135
|
-
# added 2010-02-11 15:11 RFED16 so we don't need a form.
|
136
|
-
@win_left = 0
|
137
|
-
@win_top = 0
|
138
|
-
@current_column = 0
|
139
|
-
# currently i scroll right only if current line is longer than display width, i should use
|
140
|
-
# longest line on screen.
|
141
|
-
@longest_line = 0 # the longest line printed on this page, used to determine if scrolling shd work
|
142
|
-
list_init_vars
|
143
|
-
|
144
|
-
end
|
145
|
-
def map_keys
|
146
|
-
# remove bindings from here. we call repeatedly
|
147
|
-
bind_key([?g,?g]){ goto_start } # mapping double keys like vim
|
148
|
-
bind_key([?',?']){ goto_last_position } # vim , goto last row position (not column)
|
149
|
-
bind_key(?/, :ask_search) # XXX TESTME
|
150
|
-
bind_key(?n, :find_more) # XXX TESTME
|
151
|
-
bind_key([?\C-x, ?>], :scroll_right)
|
152
|
-
bind_key([?\C-x, ?<], :scroll_left)
|
153
|
-
#bind_key(?r) { getstr("Enter a word: ") }
|
154
|
-
bind_key(?m, :disp_menu) # enhance this or cut it out - how can app leverage this. TODO
|
155
|
-
bind_key(?w, :next_column)
|
156
|
-
bind_key(?b, :previous_column)
|
157
|
-
list_bindings
|
158
|
-
end
|
159
|
-
|
160
|
-
#
|
161
|
-
# set column names
|
162
|
-
# @param [Array] column names or headings
|
163
|
-
#
|
164
|
-
def columns=(array)
|
165
|
-
@_header_adjustment = 1
|
166
|
-
@columns = array
|
167
|
-
@columns.each_with_index { |c,i|
|
168
|
-
@cw[i] ||= c.to_s.length
|
169
|
-
@calign[i] ||= :left
|
170
|
-
}
|
171
|
-
# maintains index in current pointer and gives next or prev
|
172
|
-
@column_pointer = Circular.new @columns.size()-1
|
173
|
-
end
|
174
|
-
alias :headings= :columns=
|
175
|
-
##
|
176
|
-
# send in a list of data
|
177
|
-
# sorting will only happen if data passed using set_content
|
178
|
-
# NOTE: why doesn't set_content take in columns
|
179
|
-
# @param [Array / Tabular] data to be displayed
|
180
|
-
def set_content list, columns=nil
|
181
|
-
if list.is_a? RubyCurses::Tabular
|
182
|
-
@list = list
|
183
|
-
elsif list.is_a? Array
|
184
|
-
@list = list
|
185
|
-
else
|
186
|
-
raise "set_content expects Array not #{list.class}"
|
187
|
-
end
|
188
|
-
if @table_row_sorter
|
189
|
-
@table_row_sorter.model=@list
|
190
|
-
else
|
191
|
-
@table_row_sorter = TableRowSorter.new @list
|
192
|
-
end
|
193
|
-
# adding columns setting here 2011-10-16
|
194
|
-
self.columns = columns if columns
|
195
|
-
@current_index = @_header_adjustment # but this is set when columns passed
|
196
|
-
@toprow = 0
|
197
|
-
@second_time = false # so that reestimation of column_widths
|
198
|
-
@repaint_required = true
|
199
|
-
@recalc_required = true
|
200
|
-
self
|
201
|
-
end
|
202
|
-
def data=(data)
|
203
|
-
set_content(data, nil)
|
204
|
-
end
|
205
|
-
|
206
|
-
# add a row of data
|
207
|
-
# NOTE: this is not creating a table sorter
|
208
|
-
# @param [Array] an array containing entries for each column
|
209
|
-
def add array
|
210
|
-
@list ||= []
|
211
|
-
@list << array
|
212
|
-
@repaint_required = true
|
213
|
-
@recalc_required = true
|
214
|
-
end
|
215
|
-
alias :<< :add
|
216
|
-
alias :add_row :add
|
217
|
-
alias :append :add
|
218
|
-
def create_default_sorter
|
219
|
-
raise "Data not sent in." unless @list
|
220
|
-
@table_row_sorter = TableRowSorter.new @list
|
221
|
-
end
|
222
|
-
def remove_all
|
223
|
-
@list = []
|
224
|
-
init_vars
|
225
|
-
end
|
226
|
-
def delete_at off0
|
227
|
-
ret=@list.delete_at off0
|
228
|
-
return ret
|
229
|
-
end
|
230
|
-
def []=(off0, data)
|
231
|
-
@list[off0] = data
|
232
|
-
end
|
233
|
-
def [](off0)
|
234
|
-
@list[off0]
|
235
|
-
end
|
236
|
-
def insert off0, *data
|
237
|
-
@list.insert off0, *data
|
238
|
-
end
|
239
|
-
# TODO more methods like in listbox so interchangeable, delete_at etc
|
240
|
-
def column_width colindex, width
|
241
|
-
return if width < 0
|
242
|
-
raise ArgumentError, "wrong width value sent: #{width} " if width.nil? || !width.is_a?(Fixnum) || width < 0
|
243
|
-
#@cw[colindex] = width
|
244
|
-
@pw[colindex] = width # XXXXX
|
245
|
-
get_column(colindex).width = width
|
246
|
-
@repaint_required = true
|
247
|
-
@recalc_required = true
|
248
|
-
end
|
249
|
-
|
250
|
-
# set alignment of given column offset
|
251
|
-
# @param [Number] column offset, starting 0
|
252
|
-
# @param [Symbol] :left, :right
|
253
|
-
def column_align colindex, lrc
|
254
|
-
raise ArgumentError, "wrong alignment value sent" if ![:right, :left, :center].include? lrc
|
255
|
-
@calign[colindex] = lrc
|
256
|
-
get_column(colindex).align = lrc
|
257
|
-
@repaint_required = true
|
258
|
-
#@recalc_required = true
|
259
|
-
end
|
260
|
-
# Set a column to hidden TODO we are not actually doing that
|
261
|
-
def column_hidden colindex, tf=true
|
262
|
-
#raise ArgumentError, "wrong alignment value sent" if ![:right, :left, :center].include? lrc
|
263
|
-
get_column(colindex).hidden = tf
|
264
|
-
@repaint_required = true
|
265
|
-
@recalc_required = true
|
266
|
-
end
|
267
|
-
def move_column
|
268
|
-
|
269
|
-
end
|
270
|
-
def expand_column
|
271
|
-
end
|
272
|
-
def contract_column
|
273
|
-
end
|
274
|
-
## display this row number on top
|
275
|
-
# programmataically indicate a row to be top row
|
276
|
-
def top_row(*val)
|
277
|
-
if val.empty?
|
278
|
-
@toprow
|
279
|
-
else
|
280
|
-
@toprow = val[0] || 0
|
281
|
-
end
|
282
|
-
@repaint_required = true
|
283
|
-
end
|
284
|
-
## ---- for listscrollable ---- ##
|
285
|
-
def scrollatrow #:nodoc:
|
286
|
-
# TODO account for headers
|
287
|
-
if @suppress_borders
|
288
|
-
@height - @_header_adjustment
|
289
|
-
else
|
290
|
-
@height - (2 + @_header_adjustment)
|
291
|
-
end
|
292
|
-
end
|
293
|
-
def row_count
|
294
|
-
#@list.length
|
295
|
-
get_content().length + @_header_adjustment
|
296
|
-
end
|
297
|
-
##
|
298
|
-
# returns row of first match of given regex (or nil if not found)
|
299
|
-
def find_first_match regex #:nodoc:
|
300
|
-
@list.each_with_index do |row, ix|
|
301
|
-
return ix if !row.match(regex).nil?
|
302
|
-
end
|
303
|
-
return nil
|
304
|
-
end
|
305
|
-
## returns the position where cursor was to be positioned by default
|
306
|
-
# It may no longer work like that.
|
307
|
-
def rowcol #:nodoc:
|
308
|
-
return @row+@row_offset, @col+@col_offset
|
309
|
-
end
|
310
|
-
## print a border
|
311
|
-
## Note that print_border clears the area too, so should be used sparingly.
|
312
|
-
def print_borders #:nodoc:
|
313
|
-
raise "#{self.class} needs width" unless @width
|
314
|
-
raise "#{self.class} needs height" unless @height
|
315
|
-
|
316
|
-
$log.debug " #{@name} print_borders, #{@graphic.name} "
|
317
|
-
|
318
|
-
bordercolor = @border_color || $datacolor
|
319
|
-
borderatt = @border_attrib || Ncurses::A_NORMAL
|
320
|
-
@graphic.print_border @row, @col, @height-1, @width, bordercolor, borderatt
|
321
|
-
print_title
|
322
|
-
end
|
323
|
-
def print_title #:nodoc:
|
324
|
-
raise "#{self.class} needs width" unless @width
|
325
|
-
$log.debug " print_title #{@row}, #{@col}, #{@width} "
|
326
|
-
@graphic.printstring( @row, @col+(@width-@title.length)/2, @title, $datacolor, @title_attrib) unless @title.nil?
|
327
|
-
end
|
328
|
-
def print_foot #:nodoc:
|
329
|
-
@footer_attrib ||= Ncurses::A_DIM
|
330
|
-
gb = get_color($datacolor, 'green','black')
|
331
|
-
if @current_index == @toprow
|
332
|
-
footer = "%15s" % " [ header row ]"
|
333
|
-
else
|
334
|
-
footer = "%15s" % " [#{@current_index}/ #{@list.length} ]"
|
335
|
-
end
|
336
|
-
pos = @col + 2
|
337
|
-
right = true
|
338
|
-
if right
|
339
|
-
pos = @col + @width - footer.length - 1
|
340
|
-
end
|
341
|
-
@graphic.printstring( @row + @height -1 , pos, footer, gb, @footer_attrib)
|
342
|
-
@repaint_footer_required = false # 2010-01-23 22:55
|
343
|
-
#@footer_attrib ||= Ncurses::A_REVERSE
|
344
|
-
#footer = "R: #{@current_index+1}, C: #{@curpos+@pcol}, #{@list.length} lines "
|
345
|
-
##$log.debug " print_foot calling printstring with #{@row} + #{@height} -1, #{@col}+2"
|
346
|
-
#@graphic.printstring( @row + @height -1 , @col+2, footer, $datacolor, @footer_attrib)
|
347
|
-
#@repaint_footer_required = false # 2010-01-23 22:55
|
348
|
-
end
|
349
|
-
### FOR scrollable ###
|
350
|
-
def get_content
|
351
|
-
@list
|
352
|
-
#[:columns, :separator, *@list]
|
353
|
-
#[:columns, *@list]
|
354
|
-
end
|
355
|
-
def get_window #:nodoc:
|
356
|
-
@graphic
|
357
|
-
end
|
358
|
-
|
359
|
-
def repaint # Tabularwidget :nodoc:
|
360
|
-
|
361
|
-
#return unless @repaint_required # 2010-02-12 19:08 TRYING - won't let footer print for col move
|
362
|
-
paint if @repaint_required
|
363
|
-
# raise "TV 175 graphic nil " unless @graphic
|
364
|
-
print_foot if @print_footer && @repaint_footer_required
|
365
|
-
end
|
366
|
-
def getvalue
|
367
|
-
@list
|
368
|
-
end
|
369
|
-
# returns value of current row.
|
370
|
-
# NOTE: you may need to adjust it with _header_adjustment - actually you can't
|
371
|
-
# this may give wrong row -- depends what you want.
|
372
|
-
def current_value
|
373
|
-
@list[@current_index-@_header_adjustment] # XXX added header_adju 2010-11-01 11:14
|
374
|
-
end
|
375
|
-
def real_index
|
376
|
-
@current_index-@_header_adjustment # XXX added header_adju 2010-11-06 19:38
|
377
|
-
end
|
378
|
-
# Tabularwidget
|
379
|
-
def handle_key ch #:nodoc:
|
380
|
-
if header_row?
|
381
|
-
ret = header_handle_key ch
|
382
|
-
return ret unless ret == :UNHANDLED
|
383
|
-
end
|
384
|
-
case ch
|
385
|
-
when ?\C-d.getbyte(0) #, 32
|
386
|
-
scroll_forward
|
387
|
-
when ?\C-b.getbyte(0)
|
388
|
-
scroll_backward
|
389
|
-
when ?\C-[.getbyte(0), ?t.getbyte(0)
|
390
|
-
goto_start #start of buffer # cursor_start
|
391
|
-
when ?\C-].getbyte(0), ?G.getbyte(0)
|
392
|
-
goto_end # end / bottom cursor_end
|
393
|
-
when KEY_UP, ?k.getbyte(0)
|
394
|
-
#select_prev_row
|
395
|
-
ret = up
|
396
|
-
get_window.ungetch(KEY_BTAB) if ret == :NO_PREVIOUS_ROW
|
397
|
-
check_curpos
|
398
|
-
|
399
|
-
when KEY_DOWN, ?j.getbyte(0)
|
400
|
-
ret = down
|
401
|
-
#get_window.ungetch(KEY_TAB) if ret == :NO_NEXT_ROW
|
402
|
-
check_curpos
|
403
|
-
when KEY_LEFT, ?h.getbyte(0)
|
404
|
-
cursor_backward
|
405
|
-
when KEY_RIGHT, ?l.getbyte(0)
|
406
|
-
cursor_forward
|
407
|
-
when KEY_BACKSPACE, KEY_BSPACE, KEY_DELETE
|
408
|
-
cursor_backward
|
409
|
-
when ?\C-a.getbyte(0) #, ?0.getbyte(0)
|
410
|
-
# take care of data that exceeds maxlen by scrolling and placing cursor at start
|
411
|
-
@repaint_required = true if @pcol > 0 # tried other things but did not work
|
412
|
-
set_form_col 0
|
413
|
-
@pcol = 0
|
414
|
-
when ?\C-e.getbyte(0), ?$.getbyte(0)
|
415
|
-
# take care of data that exceeds maxlen by scrolling and placing cursor at end
|
416
|
-
# This use to actually pan the screen to actual end of line, but now somewhere
|
417
|
-
# it only goes to end of visible screen, set_form probably does a sanity check
|
418
|
-
blen = @buffer.rstrip.length
|
419
|
-
set_form_col blen
|
420
|
-
# search related
|
421
|
-
when @KEY_ASK_FIND # FIXME
|
422
|
-
ask_search
|
423
|
-
when @KEY_FIND_MORE # FIXME
|
424
|
-
find_more
|
425
|
-
when 10, 13, KEY_ENTER
|
426
|
-
#fire_handler :PRESS, self
|
427
|
-
fire_action_event
|
428
|
-
when ?0.getbyte(0)..?9.getbyte(0)
|
429
|
-
# FIXME the assumption here was that if numbers are being entered then a 0 is a number
|
430
|
-
# not a beg-of-line command.
|
431
|
-
# However, after introducing universal_argument, we can enters numbers using C-u and then press another
|
432
|
-
# C-u to stop. In that case a 0 should act as a command, even though multiplier has been set
|
433
|
-
if ch == ?0.getbyte(0) and $multiplier == 0
|
434
|
-
# copy of C-a - start of line
|
435
|
-
@repaint_required = true if @pcol > 0 # tried other things but did not work
|
436
|
-
set_form_col 0
|
437
|
-
@pcol = 0
|
438
|
-
return 0
|
439
|
-
end
|
440
|
-
# storing digits entered so we can multiply motion actions
|
441
|
-
$multiplier *= 10 ; $multiplier += (ch-48)
|
442
|
-
return 0
|
443
|
-
#when ?\C-u.getbyte(0)
|
444
|
-
## multiplier. Series is 4 16 64
|
445
|
-
#@multiplier = (@multiplier == 0 ? 4 : @multiplier *= 4)
|
446
|
-
#return 0
|
447
|
-
when ?\M-l.getbyte(0) # just added 2010-03-05 not perfect
|
448
|
-
scroll_right # scroll data horizontally
|
449
|
-
when ?\M-h.getbyte(0)
|
450
|
-
scroll_left
|
451
|
-
when ?\C-c.getbyte(0)
|
452
|
-
$multiplier = 0
|
453
|
-
return 0
|
454
|
-
else
|
455
|
-
# check for bindings, these cannot override above keys since placed at end
|
456
|
-
begin
|
457
|
-
ret = process_key ch, self
|
458
|
-
rescue => err
|
459
|
-
$error_message.value = err.to_s
|
460
|
-
# @form.window.print_error_message # changed 2011 dts
|
461
|
-
alert err.to_s
|
462
|
-
$log.error " Tabularwidget ERROR #{err} "
|
463
|
-
$log.debug(err.backtrace.join("\n"))
|
464
|
-
# XXX caller app has no idea error occurred so can't do anything !
|
465
|
-
end
|
466
|
-
return :UNHANDLED if ret == :UNHANDLED
|
467
|
-
end
|
468
|
-
$multiplier = 0 # you must reset if you've handled a key. if unhandled, don't reset since parent could use
|
469
|
-
set_form_row
|
470
|
-
return 0 # added 2010-01-12 22:17 else down arrow was going into next field
|
471
|
-
end
|
472
|
-
#
|
473
|
-
# allow header to handle keys
|
474
|
-
# NOTE: header could become an object in near future
|
475
|
-
# We are calling a resize event and passing column index but do we really
|
476
|
-
# have a column object that user can access and do something with ?? XXX
|
477
|
-
#
|
478
|
-
def header_handle_key ch #:nodoc:
|
479
|
-
# TODO pressing = should revert to calculated size ?
|
480
|
-
col = _convert_curpos_to_column
|
481
|
-
#width = @cw[col]
|
482
|
-
width = @pw[col] || @cw[col]
|
483
|
-
case ch
|
484
|
-
when ?-.getbyte(0)
|
485
|
-
column_width col, width-1
|
486
|
-
# if this event has not been used in a sample it could change in near future
|
487
|
-
e = ColumnResizeEvent.new self, col, :DECREASE
|
488
|
-
fire_handler :COLUMN_RESIZE_EVENT, e
|
489
|
-
# can fire_hander so user can resize another column
|
490
|
-
return 0
|
491
|
-
when ?\+.getbyte(0)
|
492
|
-
column_width col, width+1
|
493
|
-
# if this event has not been used in a sample it could change in near future
|
494
|
-
e = ColumnResizeEvent.new self, col, :INCREASE
|
495
|
-
return 0
|
496
|
-
end
|
497
|
-
return :UNHANDLED
|
498
|
-
end
|
499
|
-
# newly added to check curpos when moving up or down
|
500
|
-
def check_curpos #:nodoc:
|
501
|
-
# if the cursor is ahead of data in this row then move it back
|
502
|
-
# i don't think this is required
|
503
|
-
return
|
504
|
-
if @pcol+@curpos > @buffer.length
|
505
|
-
addcol((@pcol+@buffer.length-@curpos)+1)
|
506
|
-
@curpos = @buffer.length
|
507
|
-
maxlen = (@maxlen || @width-@internal_width)
|
508
|
-
|
509
|
-
# even this row is gt maxlen, i.e., scrolled right
|
510
|
-
if @curpos > maxlen
|
511
|
-
@pcol = @curpos - maxlen
|
512
|
-
@curpos = maxlen-1
|
513
|
-
else
|
514
|
-
# this row is within maxlen, make scroll 0
|
515
|
-
@pcol=0
|
516
|
-
end
|
517
|
-
set_form_col
|
518
|
-
end
|
519
|
-
end
|
520
|
-
# set cursor on correct column tview
|
521
|
-
def set_form_col col1=@curpos #:nodoc:
|
522
|
-
@cols_panned ||= 0
|
523
|
-
@pad_offset ||= 0 # added 2010-02-11 21:54 since padded widgets get an offset.
|
524
|
-
@curpos = col1
|
525
|
-
maxlen = @maxlen || @width-@internal_width
|
526
|
-
#@curpos = maxlen if @curpos > maxlen
|
527
|
-
if @curpos > maxlen
|
528
|
-
@pcol = @curpos - maxlen
|
529
|
-
@curpos = maxlen - 1
|
530
|
-
@repaint_required = true # this is required so C-e can pan screen
|
531
|
-
else
|
532
|
-
@pcol = 0
|
533
|
-
end
|
534
|
-
# the rest only determines cursor placement
|
535
|
-
win_col = 0 # 2010-02-07 23:19 new cursor stuff
|
536
|
-
col2 = win_col + @col + @col_offset + @curpos + @cols_panned + @pad_offset
|
537
|
-
#$log.debug "TV SFC #{@name} setting c to #{col2} #{win_col} #{@col} #{@col_offset} #{@curpos} "
|
538
|
-
#@form.setrowcol @form.row, col
|
539
|
-
setrowcol nil, col2
|
540
|
-
@repaint_footer_required = true
|
541
|
-
end
|
542
|
-
def cursor_forward #:nodoc:
|
543
|
-
maxlen = @maxlen || @width-@internal_width
|
544
|
-
repeatm {
|
545
|
-
if @curpos < @width and @curpos < maxlen-1 # else it will do out of box
|
546
|
-
@curpos += 1
|
547
|
-
addcol 1
|
548
|
-
else
|
549
|
-
@pcol += 1 if @pcol <= @buffer.length
|
550
|
-
end
|
551
|
-
}
|
552
|
-
set_form_col
|
553
|
-
#@repaint_required = true
|
554
|
-
@repaint_footer_required = true # 2010-01-23 22:41
|
555
|
-
end
|
556
|
-
def addcol num #:nodoc:
|
557
|
-
#@repaint_required = true
|
558
|
-
@repaint_footer_required = true # 2010-01-23 22:41
|
559
|
-
if @form
|
560
|
-
@form.addcol num
|
561
|
-
else
|
562
|
-
@parent_component.form.addcol num
|
563
|
-
end
|
564
|
-
end
|
565
|
-
def addrowcol row,col #:nodoc:
|
566
|
-
#@repaint_required = true
|
567
|
-
@repaint_footer_required = true # 2010-01-23 22:41
|
568
|
-
if @form
|
569
|
-
@form.addrowcol row, col
|
570
|
-
else
|
571
|
-
@parent_component.form.addrowcol num
|
572
|
-
end
|
573
|
-
end
|
574
|
-
def cursor_backward #:nodoc:
|
575
|
-
repeatm {
|
576
|
-
if @curpos > 0
|
577
|
-
@curpos -= 1
|
578
|
-
set_form_col
|
579
|
-
#addcol -1
|
580
|
-
elsif @pcol > 0
|
581
|
-
@pcol -= 1
|
582
|
-
end
|
583
|
-
}
|
584
|
-
#@repaint_required = true
|
585
|
-
@repaint_footer_required = true # 2010-01-23 22:41
|
586
|
-
end
|
587
|
-
|
588
|
-
## NOTE: earlier print_border was called only once in constructor, but when
|
589
|
-
##+ a window is resized, and destroyed, then this was never called again, so the
|
590
|
-
##+ border would not be seen in splitpane unless the width coincided exactly with
|
591
|
-
##+ what is calculated in divider_location.
|
592
|
-
def paint #:nodoc:
|
593
|
-
my_win = nil
|
594
|
-
if @form
|
595
|
-
my_win = @form.window
|
596
|
-
else
|
597
|
-
my_win = @target_window
|
598
|
-
end
|
599
|
-
@graphic = my_win unless @graphic
|
600
|
-
@win_left = my_win.left
|
601
|
-
@win_top = my_win.top
|
602
|
-
tm = get_content
|
603
|
-
rc = tm.length
|
604
|
-
_estimate_column_widths if rc > 0 # will set preferred_width 2011-10-4
|
605
|
-
@left_margin ||= @row_selected_symbol.length
|
606
|
-
@width ||= @preferred_width
|
607
|
-
|
608
|
-
@height ||= [tm.length+3, 10].min
|
609
|
-
_prepare_format
|
610
|
-
|
611
|
-
print_borders if (@suppress_borders == false && @repaint_all) # do this once only, unless everything changes
|
612
|
-
_maxlen = @maxlen || @width-@internal_width
|
613
|
-
$log.debug " #{@name} Tabularwidget repaint width is #{@width}, height is #{@height} , maxlen #{maxlen}/ #{@maxlen}, #{@graphic.name} roff #{@row_offset} coff #{@col_offset}"
|
614
|
-
tr = @toprow
|
615
|
-
acolor = get_color $datacolor
|
616
|
-
h = scrollatrow()
|
617
|
-
r,c = rowcol
|
618
|
-
print_header
|
619
|
-
r += @_header_adjustment # for column header
|
620
|
-
@longest_line = @width #maxlen
|
621
|
-
0.upto(h - @_header_adjustment) do |hh|
|
622
|
-
crow = tr+hh
|
623
|
-
if crow < rc
|
624
|
-
#focussed = @current_index == crow ? true : false
|
625
|
-
content = tm[crow]
|
626
|
-
|
627
|
-
columnrow = false
|
628
|
-
if content == :columns
|
629
|
-
columnrow = true
|
630
|
-
end
|
631
|
-
|
632
|
-
value = convert_value_to_text content, crow
|
633
|
-
|
634
|
-
@buffer = value if crow == @current_index
|
635
|
-
# next call modified string. you may wanna dup the string.
|
636
|
-
# rlistbox does
|
637
|
-
sanitize value if @sanitization_required
|
638
|
-
truncate value
|
639
|
-
## set the selector symbol if requested
|
640
|
-
paint_selector crow, r+hh, c, acolor, @attr
|
641
|
-
|
642
|
-
#@graphic.printstring r+hh, c, "%-*s" % [@width-@internal_width,value], acolor, @attr
|
643
|
-
#print_data_row( r+hh, c, "%-*s" % [@width-@internal_width,value], acolor, @attr)
|
644
|
-
print_data_row( r+hh, c+@left_margin, @width-@internal_width-@left_margin, value, acolor, @attr)
|
645
|
-
|
646
|
-
else
|
647
|
-
# clear rows
|
648
|
-
@graphic.printstring r+hh, c, " " * (@width-@internal_width-@left_margin), acolor,@attr
|
649
|
-
end
|
650
|
-
end
|
651
|
-
@repaint_required = false
|
652
|
-
@repaint_footer_required = true
|
653
|
-
@repaint_all = false
|
654
|
-
|
655
|
-
end
|
656
|
-
|
657
|
-
# print data rows
|
658
|
-
def print_data_row r, c, len, value, color, attr
|
659
|
-
@graphic.printstring r, c, "%-*s" % [len,value], color, attr
|
660
|
-
end
|
661
|
-
#
|
662
|
-
# Truncates data to fit into display area.
|
663
|
-
# Copied from listscrollable since we need to take care of left_margin
|
664
|
-
# 2011-10-6 This may need to be reflected in listbox and others FIXME
|
665
|
-
def truncate content #:nodoc:
|
666
|
-
#maxlen = @maxlen || @width-2
|
667
|
-
_maxlen = @maxlen || @width-@internal_width
|
668
|
-
_maxlen = @width-@internal_width if _maxlen > @width-@internal_width
|
669
|
-
_maxlen -= @left_margin
|
670
|
-
if !content.nil?
|
671
|
-
if content.length > _maxlen # only show maxlen
|
672
|
-
@longest_line = content.length if content.length > @longest_line
|
673
|
-
#content = content[@pcol..@pcol+_maxlen-1]
|
674
|
-
content.replace content[@pcol..@pcol+_maxlen-1]
|
675
|
-
else
|
676
|
-
# can this be avoided if pcol is 0 XXX
|
677
|
-
content.replace content[@pcol..-1] if @pcol > 0
|
678
|
-
end
|
679
|
-
end
|
680
|
-
content
|
681
|
-
end
|
682
|
-
|
683
|
-
# print header row
|
684
|
-
# allows user to override
|
685
|
-
def print_header_row r, c, len, value, color, attr
|
686
|
-
#acolor = $promptcolor
|
687
|
-
@graphic.printstring r, c+@left_margin, "%-*s" % [len-@left_margin ,value], color, attr
|
688
|
-
end
|
689
|
-
def separator
|
690
|
-
#return @separ if @separ
|
691
|
-
str = ""
|
692
|
-
if @numbering
|
693
|
-
rows = @list.size.to_s.length
|
694
|
-
str = "-"*(rows+1)+@x
|
695
|
-
end
|
696
|
-
@cw.each_pair { |k,v| str << "-" * (v+1) + @x }
|
697
|
-
@separ = str.chop
|
698
|
-
end
|
699
|
-
# prints the column headers
|
700
|
-
# Uses +convert_value_to_text+ and +print_header_row+
|
701
|
-
def print_header
|
702
|
-
r,c = rowcol
|
703
|
-
value = convert_value_to_text :columns, 0
|
704
|
-
len = @width - @internal_width
|
705
|
-
truncate value # else it can later suddenly exceed line
|
706
|
-
@header_color_pair ||= get_color $promptcolor, @header_fgcolor, @header_bgcolor
|
707
|
-
@header_attrib ||= @attr
|
708
|
-
print_header_row r, c, len, value, @header_color_pair, @header_attrib
|
709
|
-
end
|
710
|
-
# convert data object to a formatted string for print
|
711
|
-
# NOTE: useful for overriding and doing custom formatting
|
712
|
-
# @param [Array] array of column data, mostly +String+
|
713
|
-
# Can also be :columns or :separator
|
714
|
-
# @param [Fixnum] index of row in data
|
715
|
-
def convert_value_to_text r, count
|
716
|
-
if r == :separator
|
717
|
-
return separator
|
718
|
-
elsif r == :columns
|
719
|
-
return "??" unless @columns # column was requested but not supplied
|
720
|
-
# FIXME putting entire header into this, take care of hidden
|
721
|
-
r = []
|
722
|
-
@columns.each_with_index { |e, i| r << e unless get_column(i).hidden }
|
723
|
-
return @headerfmtstr % r if @numbering
|
724
|
-
end
|
725
|
-
str = ""
|
726
|
-
|
727
|
-
if @numbering
|
728
|
-
#r = r.dup
|
729
|
-
#r.insert 0, count+1
|
730
|
-
# TODO get the width
|
731
|
-
str << "%*d |"% [2, count + 1]
|
732
|
-
end
|
733
|
-
# unroll r, get width and align
|
734
|
-
# This is to truncate column to requested width
|
735
|
-
fmta = []
|
736
|
-
r.each_with_index { |e, i|
|
737
|
-
next if get_column(i).hidden == true
|
738
|
-
#w = @pw[i] || @cw[i] # XXX
|
739
|
-
#$log.debug "WIDTH XXX #{i} w= #{w} , #{@pw[i]}, #{@cw[i]} :: #{e} " if $log.debug?
|
740
|
-
w = @cw[i]
|
741
|
-
l = e.to_s.length
|
742
|
-
fmt = "%-#{w}s "
|
743
|
-
if l > w
|
744
|
-
fmt = "%.#{w}s "
|
745
|
-
else
|
746
|
-
# ack we don;t need to recalc this we can pull out of hash FIXME
|
747
|
-
case @calign[i]
|
748
|
-
when :right
|
749
|
-
fmt = "%#{w}s "
|
750
|
-
else
|
751
|
-
fmt = "%-#{w}s "
|
752
|
-
end
|
753
|
-
end
|
754
|
-
str << fmt % e
|
755
|
-
fmta << fmt
|
756
|
-
}
|
757
|
-
#fmstr = fmta.join(@y)
|
758
|
-
#return fmstr % r; # FIXME hidden column still goes int
|
759
|
-
return str
|
760
|
-
end
|
761
|
-
# perhaps we can delete this since it does not respect @pw
|
762
|
-
# @deprecated (see _estimate_column_widths)
|
763
|
-
def _guess_col_widths #:nodoc:
|
764
|
-
return if @second_time
|
765
|
-
@second_time = true if @list.size > 0
|
766
|
-
@list.each_with_index { |r, i|
|
767
|
-
break if i > 10
|
768
|
-
next if r == :separator
|
769
|
-
r.each_with_index { |c, j|
|
770
|
-
x = c.to_s.length
|
771
|
-
if @cw[j].nil?
|
772
|
-
@cw[j] = x
|
773
|
-
else
|
774
|
-
@cw[j] = x if x > @cw[j]
|
775
|
-
end
|
776
|
-
}
|
777
|
-
}
|
778
|
-
#sum = @cw.values.inject(0) { |mem, var| mem + var }
|
779
|
-
#$log.debug " SUM is #{sum} "
|
780
|
-
total = 0
|
781
|
-
@cw.each_pair { |name, val| total += val }
|
782
|
-
@preferred_width = total + (@cw.size() *2)
|
783
|
-
@preferred_width += 4 if @numbering # FIXME this 4 is rough
|
784
|
-
end
|
785
|
-
def _estimate_column_widths #:nodoc:
|
786
|
-
return unless @estimate_column_widths
|
787
|
-
@estimate_column_widths = false # XXX testing why its failing in gmail
|
788
|
-
@columns.each_with_index { |c, i|
|
789
|
-
if @pw[i]
|
790
|
-
@cw[i] = @pw[i]
|
791
|
-
else
|
792
|
-
@cw[i] = calculate_column_width(i)
|
793
|
-
end
|
794
|
-
}
|
795
|
-
total = 0
|
796
|
-
@cw.each_pair { |name, val| total += val }
|
797
|
-
@preferred_width = total + (@cw.size() *2)
|
798
|
-
@preferred_width += 4 if @numbering # FIXME this 4 is rough
|
799
|
-
end
|
800
|
-
# if user has not specified preferred_width for a column
|
801
|
-
# then we can calculate the same based on data
|
802
|
-
def calculate_column_width col
|
803
|
-
ret = @cw[col] || 2
|
804
|
-
ctr = 0
|
805
|
-
@list.each_with_index { |r, i|
|
806
|
-
#next if i < @toprow # this is also a possibility, it checks visible rows
|
807
|
-
break if ctr > 10
|
808
|
-
ctr += 1
|
809
|
-
next if r == :separator
|
810
|
-
c = r[col]
|
811
|
-
x = c.to_s.length
|
812
|
-
ret = x if x > ret
|
813
|
-
}
|
814
|
-
ret
|
815
|
-
end
|
816
|
-
def _prepare_format #:nodoc:
|
817
|
-
@fmtstr = nil
|
818
|
-
fmt = []
|
819
|
-
total = 0
|
820
|
-
@cw.each_with_index { |c, i|
|
821
|
-
next if get_column(i).hidden == true # added 2010-10-28 19:08
|
822
|
-
w = @cw[i]
|
823
|
-
@coffsets[i] = total
|
824
|
-
total += w + 2
|
825
|
-
|
826
|
-
case @calign[i]
|
827
|
-
when :right
|
828
|
-
fmt << "%#{w}s "
|
829
|
-
else
|
830
|
-
fmt << "%-#{w}s "
|
831
|
-
end
|
832
|
-
}
|
833
|
-
@fmstr = fmt.join(@y)
|
834
|
-
if @numbering
|
835
|
-
@rows ||= @list.size.to_s.length
|
836
|
-
@headerfmtstr = " "*(@rows+1)+@y + @fmstr
|
837
|
-
@fmstr = "%#{@rows}d "+ @y + @fmstr
|
838
|
-
@coffsets.each_pair { |name, val| @coffsets[name] = val + @rows + 2 }
|
839
|
-
end
|
840
|
-
#$log.debug " FMT : #{@fmstr} "
|
841
|
-
#alert "format: #{@fmstr} "
|
842
|
-
end
|
843
|
-
## this is just a test of prompting user for a string
|
844
|
-
#+ as an alternative to the dialog.
|
845
|
-
def getstr prompt, maxlen=10 #:nodoc:
|
846
|
-
tabc = Proc.new {|str| Dir.glob(str +"*") }
|
847
|
-
config={}; config[:tab_completion] = tabc
|
848
|
-
config[:default] = "default"
|
849
|
-
$log.debug " inside getstr before call "
|
850
|
-
ret, str = rbgetstr(@form.window, @row+@height-1, @col+1, prompt, maxlen, config)
|
851
|
-
$log.debug " rbgetstr returned #{ret} , #{str} "
|
852
|
-
return "" if ret != 0
|
853
|
-
return str
|
854
|
-
end
|
855
|
-
# this is just a test of the simple "most" menu
|
856
|
-
def disp_menu #:nodoc:
|
857
|
-
$error_message_row ||= 23 # FIXME
|
858
|
-
$error_message_col ||= 1 # FIXME
|
859
|
-
menu = PromptMenu.new self
|
860
|
-
menu.add( menu.create_mitem( 's', "Goto start ", "Going to start", Proc.new { goto_start} ))
|
861
|
-
menu.add(menu.create_mitem( 'r', "scroll right", "I have scrolled ", :scroll_right ))
|
862
|
-
menu.add(menu.create_mitem( 'l', "scroll left", "I have scrolled ", :scroll_left ))
|
863
|
-
item = menu.create_mitem( 'm', "submenu", "submenu options" )
|
864
|
-
menu1 = PromptMenu.new( self, "Submenu Options")
|
865
|
-
menu1.add(menu1.create_mitem( 's', "CASE sensitive", "Ignoring Case in search" ))
|
866
|
-
menu1.add(menu1.create_mitem( 't', "goto last position", "moved to previous position", Proc.new { goto_last_position} ))
|
867
|
-
item.action = menu1
|
868
|
-
menu.add(item)
|
869
|
-
# how do i know what's available. the application or window should know where to place
|
870
|
-
#menu.display @form.window, 23, 1, $datacolor #, menu
|
871
|
-
menu.display @form.window, $error_message_row, $error_message_col, $datacolor #, menu
|
872
|
-
end
|
873
|
-
##
|
874
|
-
# dynamically load a module and execute init method.
|
875
|
-
# Hopefully, we can get behavior like this such as vieditable or multibuffers
|
876
|
-
def load_module requirename, includename
|
877
|
-
require "rbcurse/#{requirename}"
|
878
|
-
extend Object.const_get("#{includename}")
|
879
|
-
send("#{requirename}_init") #if respond_to? "#{includename}_init"
|
880
|
-
end
|
881
|
-
|
882
|
-
# returns true if cursor is on header row
|
883
|
-
# NOTE: I have no idea why row was used here. it is not working
|
884
|
-
def header_row?
|
885
|
-
return false if @columns.nil?
|
886
|
-
#1 == @row + (@current_index-@toprow)
|
887
|
-
@current_index == @toprow
|
888
|
-
end
|
889
|
-
# on pressing ENTER we send user some info, the calling program
|
890
|
-
# would bind :PRESS
|
891
|
-
# Added a call to sort, should i still call PRESS
|
892
|
-
# or just do a sort in here and not call PRESS ???
|
893
|
-
#--
|
894
|
-
# FIXME we can create this once and reuse
|
895
|
-
#++
|
896
|
-
def fire_action_event
|
897
|
-
return unless @list
|
898
|
-
return unless @table_row_sorter
|
899
|
-
require 'rbcurse/ractionevent'
|
900
|
-
# the header event must only be used if columns passed
|
901
|
-
if header_row?
|
902
|
-
# TODO we need to fire correct even for header row, including
|
903
|
-
#alert "you are on header row: #{@columns[x]} curpos: #{@curpos}, x:#{x} "
|
904
|
-
#aev = TextActionEvent.new self, :PRESS, @columns[x], x, @curpos
|
905
|
-
x = _convert_curpos_to_column
|
906
|
-
@table_row_sorter.toggle_sort_order x
|
907
|
-
@table_row_sorter.sort
|
908
|
-
@repaint_required = true
|
909
|
-
aev = TextActionEvent.new self, :PRESS,:header, x, @curpos
|
910
|
-
else
|
911
|
-
# please check this again current_value due to _header_adjustment XXX test
|
912
|
-
aev = TextActionEvent.new self, :PRESS, current_value(), @current_index, @curpos
|
913
|
-
end
|
914
|
-
fire_handler :PRESS, aev
|
915
|
-
end
|
916
|
-
# Convert current cursor position to a table column
|
917
|
-
# calculate column based on curpos since user may not have
|
918
|
-
# user w and b keys (:next_column)
|
919
|
-
# @return [Fixnum] column index base 0
|
920
|
-
def _convert_curpos_to_column #:nodoc:
|
921
|
-
x = 0
|
922
|
-
@coffsets.each_pair { |e,i|
|
923
|
-
if @curpos < i
|
924
|
-
break
|
925
|
-
else
|
926
|
-
x += 1
|
927
|
-
end
|
928
|
-
}
|
929
|
-
x -= 1 # since we start offsets with 0, so first auto becoming 1
|
930
|
-
return x
|
931
|
-
end
|
932
|
-
def on_enter
|
933
|
-
# so cursor positioned on correct row
|
934
|
-
set_form_row
|
935
|
-
super
|
936
|
-
end
|
937
|
-
# called by listscrollable, used by scrollbar ENTER_ROW
|
938
|
-
def on_enter_row arow
|
939
|
-
fire_handler :ENTER_ROW, self
|
940
|
-
@repaint_required = true
|
941
|
-
end
|
942
|
-
# move cursor to next column
|
943
|
-
# FIXME need to account for hidden columns and numbering
|
944
|
-
def next_column
|
945
|
-
c = @column_pointer.next
|
946
|
-
cp = @coffsets[c]
|
947
|
-
#$log.debug " next_column #{c} , #{cp} "
|
948
|
-
@curpos = cp if cp
|
949
|
-
next_row() if c < @column_pointer.last_index
|
950
|
-
#addcol cp
|
951
|
-
set_form_col
|
952
|
-
end
|
953
|
-
def previous_column
|
954
|
-
c = @column_pointer.previous
|
955
|
-
cp = @coffsets[c]
|
956
|
-
#$log.debug " prev_column #{c} , #{cp} "
|
957
|
-
@curpos = cp if cp
|
958
|
-
previous_row() if c > @column_pointer.last_index
|
959
|
-
#addcol cp FIXME
|
960
|
-
set_form_col
|
961
|
-
end
|
962
|
-
private
|
963
|
-
def get_column index #:nodoc:
|
964
|
-
return @chash[index] if @chash.has_key? index
|
965
|
-
@chash[index] = ColumnInfo.new
|
966
|
-
end
|
967
|
-
|
968
|
-
# Some supporting classes
|
969
|
-
|
970
|
-
# This is our default table row sorter.
|
971
|
-
# It does a multiple sort and allows for reverse sort also.
|
972
|
-
# It's a pretty simple sorter and uses sort, not sort_by.
|
973
|
-
# Improvements welcome.
|
974
|
-
# Usage: provide model in constructor or using model method
|
975
|
-
# Call toggle_sort_order(column_index)
|
976
|
-
# Call sort.
|
977
|
-
# Currently, this sorts the provided model in-place. Future versions
|
978
|
-
# may maintain a copy, or use a table that provides a mapping of model to result.
|
979
|
-
# # TODO check if column_sortable
|
980
|
-
class TableRowSorter
|
981
|
-
attr_reader :sort_keys
|
982
|
-
def initialize model=nil
|
983
|
-
self.model = model
|
984
|
-
@columns_sort = []
|
985
|
-
@sort_keys = nil
|
986
|
-
end
|
987
|
-
def model=(model)
|
988
|
-
@model = model
|
989
|
-
@sort_keys = nil
|
990
|
-
end
|
991
|
-
def sortable colindex, tf
|
992
|
-
@columns_sort[colindex] = tf
|
993
|
-
end
|
994
|
-
def sortable? colindex
|
995
|
-
return false if @columns_sort[colindex]==false
|
996
|
-
return true
|
997
|
-
end
|
998
|
-
# should to_s be used for this column
|
999
|
-
def use_to_s colindex
|
1000
|
-
return true # TODO
|
1001
|
-
end
|
1002
|
-
# sorts the model based on sort keys and reverse flags
|
1003
|
-
# @sort_keys contains indices to sort on
|
1004
|
-
# @reverse_flags is an array of booleans, true for reverse, nil or false for ascending
|
1005
|
-
def sort
|
1006
|
-
return unless @model
|
1007
|
-
return if @sort_keys.empty?
|
1008
|
-
$log.debug "TABULAR SORT KEYS #{sort_keys} "
|
1009
|
-
@model.sort!{|x,y|
|
1010
|
-
res = 0
|
1011
|
-
@sort_keys.each { |ee|
|
1012
|
-
e = ee.abs-1 # since we had offsetted by 1 earlier
|
1013
|
-
abse = e.abs
|
1014
|
-
if ee < 0
|
1015
|
-
res = y[abse] <=> x[abse]
|
1016
|
-
else
|
1017
|
-
res = x[e] <=> y[e]
|
1018
|
-
end
|
1019
|
-
break if res != 0
|
1020
|
-
}
|
1021
|
-
res
|
1022
|
-
}
|
1023
|
-
end
|
1024
|
-
# toggle the sort order if given column offset is primary sort key
|
1025
|
-
# Otherwise, insert as primary sort key, ascending.
|
1026
|
-
def toggle_sort_order index
|
1027
|
-
index += 1 # increase by 1, since 0 won't multiple by -1
|
1028
|
-
# internally, reverse sort is maintained by multiplying number by -1
|
1029
|
-
@sort_keys ||= []
|
1030
|
-
if @sort_keys.first && index == @sort_keys.first.abs
|
1031
|
-
@sort_keys[0] *= -1
|
1032
|
-
else
|
1033
|
-
@sort_keys.delete index # in case its already there
|
1034
|
-
@sort_keys.delete(index*-1) # in case its already there
|
1035
|
-
@sort_keys.unshift index
|
1036
|
-
# don't let it go on increasing
|
1037
|
-
if @sort_keys.size > 3
|
1038
|
-
@sort_keys.pop
|
1039
|
-
end
|
1040
|
-
end
|
1041
|
-
end
|
1042
|
-
def set_sort_keys list
|
1043
|
-
@sort_keys = list
|
1044
|
-
end
|
1045
|
-
end #class
|
1046
|
-
# what about is_resizable XXX
|
1047
|
-
class ColumnInfo < Struct.new(:name, :width, :align, :hidden)
|
1048
|
-
end
|
1049
|
-
|
1050
|
-
# a structure that maintains position and gives
|
1051
|
-
# next and previous taking max index into account.
|
1052
|
-
# it also circles. Can be used for traversing next component
|
1053
|
-
# in a form, or container, or columns in a table.
|
1054
|
-
class Circular < Struct.new(:max_index, :current_index)
|
1055
|
-
attr_reader :last_index
|
1056
|
-
attr_reader :current_index
|
1057
|
-
def initialize m, c=0
|
1058
|
-
raise "max index cannot be nil" unless m
|
1059
|
-
@max_index = m
|
1060
|
-
@current_index = c
|
1061
|
-
@last_index = c
|
1062
|
-
end
|
1063
|
-
def next
|
1064
|
-
@last_index = @current_index
|
1065
|
-
if @current_index + 1 > @max_index
|
1066
|
-
@current_index = 0
|
1067
|
-
else
|
1068
|
-
@current_index += 1
|
1069
|
-
end
|
1070
|
-
end
|
1071
|
-
def previous
|
1072
|
-
@last_index = @current_index
|
1073
|
-
if @current_index - 1 < 0
|
1074
|
-
@current_index = @max_index
|
1075
|
-
else
|
1076
|
-
@current_index -= 1
|
1077
|
-
end
|
1078
|
-
end
|
1079
|
-
def is_last?
|
1080
|
-
@current_index == @max_index
|
1081
|
-
end
|
1082
|
-
end
|
1083
|
-
# for some compatibility with Table
|
1084
|
-
def set_data data, colnames_array
|
1085
|
-
set_content data
|
1086
|
-
columns = colnames_array
|
1087
|
-
end
|
1088
|
-
def get_column_name index
|
1089
|
-
@columns[index]
|
1090
|
-
end
|
1091
|
-
alias :column_name :get_column_name
|
1092
|
-
alias :column :get_column
|
1093
|
-
def method_missing(name, *args)
|
1094
|
-
name = name.to_s
|
1095
|
-
case name
|
1096
|
-
when 'cell_editing_allowed', 'editing_policy'
|
1097
|
-
# silently ignore to keep compatible with Table
|
1098
|
-
else
|
1099
|
-
raise NoMethodError, "Undefined method #{name} for TabularWidget"
|
1100
|
-
end
|
1101
|
-
end
|
1102
|
-
|
1103
|
-
end # class tabluarw
|
1104
|
-
|
1105
|
-
end # modul
|
1106
|
-
if __FILE__ == $PROGRAM_NAME
|
1107
|
-
|
1108
|
-
require 'rbcurse/app'
|
1109
|
-
App.new do
|
1110
|
-
t = TabularWidget.new @form, :row => 2, :col => 2, :height => 20, :width => 30
|
1111
|
-
t.columns = ["Name ", "Age ", " Email "]
|
1112
|
-
t.add %w{ rahul 33 r@ruby.org }
|
1113
|
-
t << %w{ _why 133 j@gnu.org }
|
1114
|
-
t << ["jane", "1331", "jane@gnu.org" ]
|
1115
|
-
t.column_align 1, :right
|
1116
|
-
t.create_default_sorter
|
1117
|
-
|
1118
|
-
s = TabularWidget.new @form, :row => 2, :col =>32 do |b|
|
1119
|
-
b.columns = %w{ country continent text }
|
1120
|
-
b << ["india","asia","a warm country" ]
|
1121
|
-
b << ["japan","asia","a cool country" ]
|
1122
|
-
b << ["russia","europe","a hot country" ]
|
1123
|
-
#b.column_width 2, 30
|
1124
|
-
end
|
1125
|
-
s.create_default_sorter
|
1126
|
-
s = TabularWidget.new @form , :row => 12, :col => 32 do |b|
|
1127
|
-
b.columns = %w{ place continent text }
|
1128
|
-
b << ["india","asia","a warm country" ]
|
1129
|
-
b << ["japan","asia","a cool country" ]
|
1130
|
-
b << ["russia","europe","a hot country" ]
|
1131
|
-
b << ["sydney","australia","a dry country" ]
|
1132
|
-
b << ["canberra","australia","a dry country" ]
|
1133
|
-
b << ["ross island","antarctica","a dry country" ]
|
1134
|
-
b << ["mount terror","antarctica","a windy country" ]
|
1135
|
-
b << ["mt erebus","antarctica","a cold place" ]
|
1136
|
-
b << ["siberia","russia","an icy city" ]
|
1137
|
-
b << ["new york","USA","a fun place" ]
|
1138
|
-
b.column_width 0, 12
|
1139
|
-
b.column_width 1, 12
|
1140
|
-
b.column_hidden 1, true
|
1141
|
-
b.numbering = true ## FIXME BROKEN
|
1142
|
-
end
|
1143
|
-
s.create_default_sorter
|
1144
|
-
require 'rbcurse/extras/scrollbar'
|
1145
|
-
sb = Scrollbar.new @form, :parent => s
|
1146
|
-
#t.column_align 1, :right
|
1147
|
-
#puts t.to_s
|
1148
|
-
#puts
|
1149
|
-
end
|
1150
|
-
end
|