cdk 0.9.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,289 @@
1
+ module CDK
2
+ module Traverse
3
+ def Traverse.resetCDKScreen(screen)
4
+ refreshDataCDKScreen(screen)
5
+ end
6
+
7
+ def Traverse.exitOKCDKScreen(screen)
8
+ screen.exit_status = CDK::SCREEN::EXITOK
9
+ end
10
+
11
+ def Traverse.exitCancelCDKScreen(screen)
12
+ screen.exit_status = CDK::SCREEN::EXITCANCEL
13
+ end
14
+
15
+ def Traverse.exitOKCDKScreenOf(obj)
16
+ exitOKCDKScreen(obj.screen)
17
+ end
18
+
19
+ def Traverse.exitCancelCDKScreenOf(obj)
20
+ exitCancelCDKScreen(obj.screen)
21
+ end
22
+
23
+ def Traverse.resetCDKScreenOf(obj)
24
+ resetCDKScreen(obj.screen)
25
+ end
26
+
27
+ # Returns the object on which the focus lies.
28
+ def Traverse.getCDKFocusCurrent(screen)
29
+ result = nil
30
+ n = screen.object_focus
31
+
32
+ if n >= 0 && n < screen.object_count
33
+ result = screen.object[n]
34
+ end
35
+
36
+ return result
37
+ end
38
+
39
+ # Set focus to the next object, returning it.
40
+ def Traverse.setCDKFocusNext(screen)
41
+ result = nil
42
+ curobj = nil
43
+ n = getFocusIndex(screen)
44
+ first = n
45
+
46
+ while true
47
+ n+= 1
48
+ if n >= screen.object_count
49
+ n = 0
50
+ end
51
+ curobj = screen.object[n]
52
+ if !(curobj.nil?) && curobj.accepts_focus
53
+ result = curobj
54
+ break
55
+ else
56
+ if n == first
57
+ break
58
+ end
59
+ end
60
+ end
61
+
62
+ setFocusIndex(screen, if !(result.nil?) then n else -1 end)
63
+ return result
64
+ end
65
+
66
+ # Set focus to the previous object, returning it.
67
+ def Traverse.setCDKFocusPrevious(screen)
68
+ result = nil
69
+ curobj = nil
70
+ n = getFocusIndex(screen)
71
+ first = n
72
+
73
+ while true
74
+ n -= 1
75
+ if n < 0
76
+ n = screen.object_count - 1
77
+ end
78
+ curobj = screen.object[n]
79
+ if !(curobj.nil?) && curobj.accepts_focus
80
+ result = curobj
81
+ break
82
+ elsif n == first
83
+ break
84
+ end
85
+ end
86
+
87
+ setFocusIndex(screen, if !(result.nil?) then n else -1 end)
88
+ return result
89
+ end
90
+
91
+ # Set focus to a specific object, returning it.
92
+ # If the object cannot be found, return nil.
93
+ def Traverse.setCDKFocusCurrent(screen, newobj)
94
+ result = nil
95
+ curobj = nil
96
+ n = getFocusIndex(screen)
97
+ first = n
98
+
99
+ while true
100
+ n += 1
101
+ if n >= screen.object_count
102
+ n = 0
103
+ end
104
+
105
+ curobj = screen.object[n]
106
+ if curobj == newobj
107
+ result = curobj
108
+ break
109
+ elsif n == first
110
+ break
111
+ end
112
+ end
113
+
114
+ setFocusIndex(screen, if !(result.nil?) then n else -1 end)
115
+ return result
116
+ end
117
+
118
+ # Set focus to the first object in the screen.
119
+ def Traverse.setCDKFocusFirst(screen)
120
+ setFocusIndex(screen, screen.object_count - 1)
121
+ return switchFocus(setCDKFocusNext(screen), nil)
122
+ end
123
+
124
+ # Set focus to the last object in the screen.
125
+ def Traverse.setCDKFocusLast(screen)
126
+ setFocusIndex(screen, 0)
127
+ return switchFocus(setCDKFocusPrevious(screen), nil)
128
+ end
129
+
130
+ def Traverse.traverseCDKOnce(screen, curobj, key_code,
131
+ function_key, func_menu_key)
132
+ case key_code
133
+ when Ncurses::KEY_BTAB
134
+ switchFocus(setCDKFocusPrevious(screen), curobj)
135
+ when CDK::KEY_TAB
136
+ switchFocus(setCDKFocusNext(screen), curobj)
137
+ when CDK.KEY_F(10)
138
+ # save data and exit
139
+ exitOKCDKScreen(screen)
140
+ when CDK.CTRL('X')
141
+ exitCancelCDKScreen(screen)
142
+ when CDK.CTRL('R')
143
+ # reset data to defaults
144
+ resetCDKScreen(screen)
145
+ setFocus(curobj)
146
+ when CDK::REFRESH
147
+ # redraw screen
148
+ screen.refresh
149
+ setFocus(curobj)
150
+ else
151
+ # not everyone wants menus, so we make them optional here
152
+ if !(func_menu_key.nil?) &&
153
+ (func_menu_key.call(key_code, function_key))
154
+ # find and enable drop down menu
155
+ screen.object.each do |object|
156
+ if !(object.nil?) && object.object_type == :MENU
157
+ Traverse.handleMenu(screen, object, curobj)
158
+ end
159
+ end
160
+ else
161
+ curobj.inject(key_code)
162
+ end
163
+ end
164
+ end
165
+
166
+ # Traverse the widgets on a screen.
167
+ def Traverse.traverseCDKScreen(screen)
168
+ result = 0
169
+ curobj = setCDKFocusFirst(screen)
170
+
171
+ unless curobj.nil?
172
+ refreshDataCDKScreen(screen)
173
+
174
+ screen.exit_status = CDK::SCREEN::NOEXIT
175
+
176
+ while !((curobj = getCDKFocusCurrent(screen)).nil?) &&
177
+ screen.exit_status == CDK::SCREEN::NOEXIT
178
+ function = []
179
+ key = curobj.getch(function)
180
+
181
+ # TODO look at more direct way to do this
182
+ check_menu_key = lambda do |key_code, function_key|
183
+ Traverse.checkMenuKey(key_code, function_key)
184
+ end
185
+
186
+
187
+ Traverse.traverseCDKOnce(screen, curobj, key,
188
+ function[0], check_menu_key)
189
+ end
190
+
191
+ if screen.exit_status == CDK::SCREEN::EXITOK
192
+ saveDataCDKScreen(screen)
193
+ result = 1
194
+ end
195
+ end
196
+ return result
197
+ end
198
+
199
+ private
200
+
201
+ def Traverse.limitFocusIndex(screen, value)
202
+ if value >= screen.object_count || value < 0
203
+ 0
204
+ else
205
+ value
206
+ end
207
+ end
208
+
209
+ def Traverse.getFocusIndex(screen)
210
+ return limitFocusIndex(screen, screen.object_focus)
211
+ end
212
+
213
+ def Traverse.setFocusIndex(screen, value)
214
+ screen.object_focus = limitFocusIndex(screen, value)
215
+ end
216
+
217
+ def Traverse.unsetFocus(obj)
218
+ Ncurses.curs_set(0)
219
+ unless obj.nil?
220
+ obj.has_focus = false
221
+ obj.unfocus
222
+ end
223
+ end
224
+
225
+ def Traverse.setFocus(obj)
226
+ unless obj.nil?
227
+ obj.has_focus = true
228
+ obj.focus
229
+ end
230
+ Ncurses.curs_set(1)
231
+ end
232
+
233
+ def Traverse.switchFocus(newobj, oldobj)
234
+ if oldobj != newobj
235
+ Traverse.unsetFocus(oldobj)
236
+ Traverse.setFocus(newobj)
237
+ end
238
+ return newobj
239
+ end
240
+
241
+ def Traverse.checkMenuKey(key_code, function_key)
242
+ key_code == CDK::KEY_ESC && !function_key
243
+ end
244
+
245
+ def Traverse.handleMenu(screen, menu, oldobj)
246
+ done = false
247
+
248
+ switchFocus(menu, oldobj)
249
+ while !done
250
+ key = menu.getch([])
251
+
252
+ case key
253
+ when CDK::KEY_TAB
254
+ done = true
255
+ when CDK::KEY_ESC
256
+ # cleanup the menu
257
+ menu.inject(key)
258
+ done = true
259
+ else
260
+ done = (menu.inject(key) >= 0)
261
+ end
262
+ end
263
+
264
+ if (newobj = Traverse.getCDKFocusCurrent(screen)).nil?
265
+ newobj = Traverse.setCDKFocusNext(screen)
266
+ end
267
+
268
+ return switchFocus(newobj, menu)
269
+ end
270
+
271
+ # Save data in widgets on a screen
272
+ def Traverse.saveDataCDKScreen(screen)
273
+ screen.object.each do |object|
274
+ unless object.nil?
275
+ object.saveData
276
+ end
277
+ end
278
+ end
279
+
280
+ # Refresh data in widgets on a screen
281
+ def Traverse.refreshDataCDKScreen(screen)
282
+ screen.object.each do |object|
283
+ unless object.nil?
284
+ object.refreshData
285
+ end
286
+ end
287
+ end
288
+ end
289
+ end
@@ -0,0 +1,14 @@
1
+ require_relative 'scale'
2
+
3
+ module CDK
4
+ class USCALE < CDK::SCALE
5
+ # The original UScale handled unsigned values.
6
+ # Since Ruby's typing is different this is really just SCALE
7
+ # but is nice it's nice to have this for compatibility/completeness
8
+ # sake.
9
+
10
+ def object_type
11
+ :USCALE
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,14 @@
1
+ require_relative 'slider'
2
+
3
+ module CDK
4
+ class USLIDER < CDK::SLIDER
5
+ # The original USlider handled unsigned values.
6
+ # Since Ruby's typing is different this is really just SLIDER
7
+ # but is nice it's nice to have this for compatibility/completeness
8
+ # sake.
9
+
10
+ def object_type
11
+ :USLIDER
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,812 @@
1
+ require_relative 'cdk_objs'
2
+
3
+ module CDK
4
+ class VIEWER < CDK::CDKOBJS
5
+ DOWN = 0
6
+ UP = 1
7
+
8
+ def initialize(cdkscreen, xplace, yplace, height, width,
9
+ buttons, button_count, button_highlight, box, shadow)
10
+ super()
11
+ parent_width = cdkscreen.window.getmaxx
12
+ parent_height = cdkscreen.window.getmaxy
13
+ box_width = width
14
+ box_height = height
15
+ button_width = 0
16
+ button_adj = 0
17
+ button_pos = 1
18
+ bindings = {
19
+ CDK::BACKCHAR => Ncurses::KEY_PPAGE,
20
+ 'b' => Ncurses::KEY_PPAGE,
21
+ 'B' => Ncurses::KEY_PPAGE,
22
+ CDK::FORCHAR => Ncurses::KEY_NPAGE,
23
+ ' ' => Ncurses::KEY_NPAGE,
24
+ 'f' => Ncurses::KEY_NPAGE,
25
+ 'F' => Ncurses::KEY_NPAGE,
26
+ '|' => Ncurses::KEY_HOME,
27
+ '$' => Ncurses::KEY_END,
28
+ }
29
+
30
+ self.setBox(box)
31
+
32
+ box_height = CDK.setWidgetDimension(parent_height, height, 0)
33
+ box_width = CDK.setWidgetDimension(parent_width, width, 0)
34
+
35
+ # Rejustify the x and y positions if we need to.
36
+ xtmp = [xplace]
37
+ ytmp = [yplace]
38
+ CDK.alignxy(cdkscreen.window, xtmp, ytmp, box_width, box_height)
39
+ xpos = xtmp[0]
40
+ ypos = ytmp[0]
41
+
42
+ # Make the viewer window.
43
+ @win= Ncurses::WINDOW.new(box_height, box_width, ypos, xpos)
44
+ if @win.nil?
45
+ self.destroy
46
+ return nil
47
+ end
48
+
49
+ # Turn the keypad on for the viewer.
50
+ @win.keypad(true)
51
+
52
+ # Create the buttons.
53
+ @button_count = button_count
54
+ @button = []
55
+ @button_len = []
56
+ @button_pos = []
57
+ if button_count > 0
58
+ (0...button_count).each do |x|
59
+ button_len = []
60
+ @button << CDK.char2Chtype(buttons[x], button_len, [])
61
+ @button_len << button_len[0]
62
+ button_width += @button_len[x] + 1
63
+ end
64
+ button_adj = (box_width - button_width) / (button_count + 1)
65
+ button_pos = 1 + button_adj
66
+ (0...button_count).each do |x|
67
+ @button_pos << button_pos
68
+ button_pos += button_adj + @button_len[x]
69
+ end
70
+ end
71
+
72
+ # Set the rest of the variables.
73
+ @screen = cdkscreen
74
+ @parent = cdkscreen.window
75
+ @shadow_win = nil
76
+ @button_highlight = button_highlight
77
+ @box_height = box_height
78
+ @box_width = box_width - 2
79
+ @view_size = height - 2
80
+ @input_window = @win
81
+ @shadow = shadow
82
+ @current_button = 0
83
+ @current_top = 0
84
+ @length = 0
85
+ @left_char = 0
86
+ @max_left_char = 0
87
+ @max_top_line = 0
88
+ @characters = 0
89
+ @list_size = -1
90
+ @show_line_info = 1
91
+ @exit_type = :EARLY_EXIT
92
+
93
+ # Do we need to create a shadow?
94
+ if shadow
95
+ @shadow_win = Ncurses::WINDOW.new(box_height, box_width + 1,
96
+ ypos + 1, xpos + 1)
97
+ if @shadow_win.nil?
98
+ self.destroy
99
+ return nil
100
+ end
101
+ end
102
+
103
+ # Setup the key bindings.
104
+ bindings.each do |from, to|
105
+ self.bind(:VIEWER, from, :getc, to)
106
+ end
107
+
108
+ cdkscreen.register(:VIEWER, self)
109
+ end
110
+
111
+ # This function sets various attributes of the widget.
112
+ def set(title, list, list_size, button_highlight,
113
+ attr_interp, show_line_info, box)
114
+ self.setTitle(title)
115
+ self.setHighlight(button_highlight)
116
+ self.setInfoLine(show_line_info)
117
+ self.setBox(box)
118
+ return self.setInfo(list, list_size, attr_interp)
119
+ end
120
+
121
+ # This sets the title of the viewer. (A nil title is allowed.
122
+ # It just means that the viewer will not have a title when drawn.)
123
+ def setTitle(title)
124
+ super(title, -(@box_width + 1))
125
+ @title_adj = @title_lines
126
+
127
+ # Need to set @view_size
128
+ @view_size = @box_height - (@title_lines + 1) - 2
129
+ end
130
+
131
+ def getTitle
132
+ return @title
133
+ end
134
+
135
+ def setupLine(interpret, list, x)
136
+ # Did they ask for attribute interpretation?
137
+ if interpret
138
+ list_len = []
139
+ list_pos = []
140
+ @list[x] = CDK.char2Chtype(list, list_len, list_pos)
141
+ @list_len[x] = list_len[0]
142
+ @list_pos[x] = CDK.justifyString(@box_width, @list_len[x], list_pos[0])
143
+ else
144
+ # We must convert tabs and other nonprinting characters. The curses
145
+ # library normally does this, but we are bypassing it by writing
146
+ # chtypes directly.
147
+ t = ''
148
+ len = 0
149
+ (0...list.size).each do |y|
150
+ if list[y] == "\t".ord
151
+ begin
152
+ t << ' '
153
+ len += 1
154
+ end while (len & 7) != 0
155
+ elsif CDK.CharOf(list[y].ord).match(/^[[:print:]]$/)
156
+ t << CDK.CharOf(list[y].ord)
157
+ len += 1
158
+ else
159
+ t << Ncurses.unctrl(list[y].ord)
160
+ len += 1
161
+ end
162
+ end
163
+ @list[x] = t
164
+ @list_len[x] = t.size
165
+ @list_pos[x] = 0
166
+ end
167
+ @widest_line = [@widest_line, @list_len[x]].max
168
+ end
169
+
170
+ def freeLine(x)
171
+ if x < @list_size
172
+ @list[x] = ''
173
+ end
174
+ end
175
+
176
+ # This function sets the contents of the viewer.
177
+ def setInfo(list, list_size, interpret)
178
+ current_line = 0
179
+ viewer_size = list_size
180
+
181
+ if list_size < 0
182
+ list_size = list.size
183
+ end
184
+
185
+ # Compute the size of the resulting display
186
+ viewer_size = list_size
187
+ if list.size > 0 && interpret
188
+ (0...list_size).each do |x|
189
+ filename = ''
190
+ if CDK.checkForLink(list[x], filename) == 1
191
+ file_contents = []
192
+ file_len = CDK.readFile(filename, file_contents)
193
+
194
+ if file_len >= 0
195
+ viewer_size += (file_len - 1)
196
+ end
197
+ end
198
+ end
199
+ end
200
+
201
+ # Clean out the old viewer info. (if there is any)
202
+ @in_progress = true
203
+ self.clean
204
+ self.createList(viewer_size)
205
+
206
+ # Keep some semi-permanent info
207
+ @interpret = interpret
208
+
209
+ # Copy the information given.
210
+ current_line = 0
211
+ x = 0
212
+ while x < list_size && current_line < viewer_size
213
+ if list[x].size == 0
214
+ @list[current_line] = ''
215
+ @list_len[current_line] = 0
216
+ @list_pos[current_line] = 0
217
+ current_line += 1
218
+ else
219
+ # Check if we have a file link in this line.
220
+ filename = []
221
+ if CDK.checkForLink(list[x], filename) == 1
222
+ # We have a link, open the file.
223
+ file_contents = []
224
+ file_len = 0
225
+
226
+ # Open the file and put it into the viewer
227
+ file_len = CDK.readFile(filename, file_contents)
228
+ if file_len == -1
229
+ fopen_fmt = if Ncurses.has_colors?
230
+ then '<C></16>Link Failed: Could not open the file %s'
231
+ else '<C></K>Link Failed: Could not open the file %s'
232
+ end
233
+ temp = fopen_fmt % filename
234
+ self.setupLine(true, temp, current_line)
235
+ current_line += 1
236
+ else
237
+ # For each line read, copy it into the viewer.
238
+ file_len = [file_len, viewer_size - current_line].min
239
+ (0...file_len).each do |file_line|
240
+ if current_line >= viewer_size
241
+ break
242
+ end
243
+ self.setupLine(false, file_contents[file_line], current_line)
244
+ @characters += @list_len[current_line]
245
+ current_line += 1
246
+ end
247
+ end
248
+ elsif current_line < viewer_size
249
+ self.setupLine(@interpret, list[x], current_line)
250
+ @characters += @list_len[current_line]
251
+ current_line += 1
252
+ end
253
+ end
254
+ x+= 1
255
+ end
256
+
257
+ # Determine how many characters we can shift to the right before
258
+ # all the items have been viewer off the screen.
259
+ if @widest_line > @box_width
260
+ @max_left_char = (@widest_line - @box_width) + 1
261
+ else
262
+ @max_left_char = 0
263
+ end
264
+
265
+ # Set up the needed vars for the viewer list.
266
+ @in_progress = false
267
+ @list_size = viewer_size
268
+ if @list_size <= @view_size
269
+ @max_top_line = 0
270
+ else
271
+ @max_top_line = @list_size - 1
272
+ end
273
+ return @list_size
274
+ end
275
+
276
+ def getInfo(size)
277
+ size << @list_size
278
+ return @list
279
+ end
280
+
281
+ # This function sets the highlight type of the buttons.
282
+ def setHighlight(button_highlight)
283
+ @button_highlight = button_highlight
284
+ end
285
+
286
+ def getHighlight
287
+ return @button_highlight
288
+ end
289
+
290
+ # This sets whether or not you wnat to set the viewer info line.
291
+ def setInfoLine(show_line_info)
292
+ @show_line_info = show_line_info
293
+ end
294
+
295
+ def getInfoLine
296
+ return @show_line_info
297
+ end
298
+
299
+ # This removes all the lines inside the scrolling window.
300
+ def clean
301
+ # Clean up the memory used...
302
+ (0...@list_size).each do |x|
303
+ self.freeLine(x)
304
+ end
305
+
306
+ # Reset some variables.
307
+ @list_size = 0
308
+ @max_left_char = 0
309
+ @widest_line = 0
310
+ @current_top = 0
311
+ @max_top_line = 0
312
+
313
+ # Redraw the window.
314
+ self.draw(@box)
315
+ end
316
+
317
+ def PatternNotFound(pattern)
318
+ temp_info = [
319
+ "</U/5>Pattern '%s' not found.<!U!5>" % pattern,
320
+ ]
321
+ self.popUpLabel(temp_info)
322
+ end
323
+
324
+ # This function actually controls the viewer...
325
+ def activate(actions)
326
+ refresh = false
327
+ # Create the information about the file stats.
328
+ file_info = [
329
+ '</5> </U>File Statistics<!U> <!5>',
330
+ '</5> <!5>',
331
+ '</5/R>Character Count:<!R> %-4d <!5>' % @characters,
332
+ '</5/R>Line Count :<!R> %-4d <!5>' % @list_size,
333
+ '</5> <!5>',
334
+ '<C></5>Press Any Key To Continue.<!5>'
335
+ ]
336
+
337
+ temp_info = ['<C></5>Press Any Key To Continue.<!5>']
338
+
339
+ # Set the current button.
340
+ @current_button = 0
341
+
342
+ # Draw the widget list.
343
+ self.draw(@box)
344
+
345
+ # Do this until KEY_ENTER is hit.
346
+ while true
347
+ # Reset the refresh flag.
348
+ refresh = false
349
+
350
+ input = self.getch([])
351
+ if !self.checkBind(:VIEWER, input)
352
+ case input
353
+ when CDK::KEY_TAB
354
+ if @button_count > 1
355
+ if @current_button == @button_count - 1
356
+ @current_button = 0
357
+ else
358
+ @current_button += 1
359
+ end
360
+
361
+ # Redraw the buttons.
362
+ self.drawButtons
363
+ end
364
+ when CDK::PREV
365
+ if @button_count > 1
366
+ if @current_button == 0
367
+ @current_button = @button_count - 1
368
+ else
369
+ @current_button -= 1
370
+ end
371
+
372
+ # Redraw the buttons.
373
+ self.drawButtons
374
+ end
375
+ when Ncurses::KEY_UP
376
+ if @current_top > 0
377
+ @current_top -= 1
378
+ refresh = true
379
+ else
380
+ CDK.Beep
381
+ end
382
+ when Ncurses::KEY_DOWN
383
+ if @current_top < @max_top_line
384
+ @current_top += 1
385
+ refresh = true
386
+ else
387
+ CDK.Beep
388
+ end
389
+ when Ncurses::KEY_RIGHT
390
+ if @left_char < @max_left_char
391
+ @left_char += 1
392
+ refresh = true
393
+ else
394
+ CDK.Beep
395
+ end
396
+ when Ncurses::KEY_LEFT
397
+ if @left_char > 0
398
+ @left_char -= 1
399
+ refresh = true
400
+ else
401
+ CDK.Beep
402
+ end
403
+ when Ncurses::KEY_PPAGE
404
+ if @current_top > 0
405
+ if @current_top - (@view_size - 1) > 0
406
+ @current_top = @current_top - (@view_size - 1)
407
+ else
408
+ @current_top = 0
409
+ end
410
+ refresh = true
411
+ else
412
+ CDK.Beep
413
+ end
414
+ when Ncurses::KEY_NPAGE
415
+ if @current_top < @max_top_line
416
+ if @current_top + @view_size < @max_top_line
417
+ @current_top = @current_top + (@view_size - 1)
418
+ else
419
+ @current_top = @max_top_line
420
+ end
421
+ refresh = true
422
+ else
423
+ CDK.Beep
424
+ end
425
+ when Ncurses::KEY_HOME
426
+ @left_char = 0
427
+ refresh = true
428
+ when Ncurses::KEY_END
429
+ @left_char = @max_left_char
430
+ refresh = true
431
+ when 'g'.ord, '1'.ord, '<'.ord
432
+ @current_top = 0
433
+ refresh = true
434
+ when 'G'.ord, '>'.ord
435
+ @current_top = @max_top_line
436
+ refresh = true
437
+ when 'L'.ord
438
+ x = (@list_size + @current_top) / 2
439
+ if x < @max_top_line
440
+ @current_top = x
441
+ refresh = true
442
+ else
443
+ CDK.Beep
444
+ end
445
+ when 'l'.ord
446
+ x = @current_top / 2
447
+ if x >= 0
448
+ @current_top = x
449
+ refresh = true
450
+ else
451
+ CDK.Beep
452
+ end
453
+ when '?'.ord
454
+ @search_direction = CDK::VIEWER::UP
455
+ self.getAndStorePattern(@screen)
456
+ if !self.searchForWord(@search_pattern, @search_direction)
457
+ self.PatternNotFound(@search_pattern)
458
+ end
459
+ refresh = true
460
+ when '/'.ord
461
+ @search_direction = CDK::VIEWER:DOWN
462
+ self.getAndStorePattern(@screen)
463
+ if !self.searchForWord(@search_pattern, @search_direction)
464
+ self.PatternNotFound(@search_pattern)
465
+ end
466
+ refresh = true
467
+ when 'N'.ord, 'n'.ord
468
+ if @search_pattern == ''
469
+ temp_info[0] = '</5>There is no pattern in the buffer.<!5>'
470
+ self.popUpLabel(temp_info)
471
+ elsif !self.searchForWord(@search_pattern,
472
+ if input == 'n'.ord
473
+ then @search_direction
474
+ else 1 - @search_direction
475
+ end)
476
+ self.PatternNotFound(@search_pattern)
477
+ end
478
+ refresh = true
479
+ when ':'.ord
480
+ @current_top = self.jumpToLine
481
+ refresh = true
482
+ when 'i'.ord, 's'.ord, 'S'.ord
483
+ self.popUpLabel(file_info)
484
+ refresh = true
485
+ when CDK::KEY_ESC
486
+ self.setExitType(input)
487
+ return -1
488
+ when Ncurses::ERR
489
+ self.setExitType(input)
490
+ return -1
491
+ when Ncurses::KEY_ENTER, CDK::KEY_RETURN
492
+ self.setExitType(input)
493
+ return @current_button
494
+ when CDK::REFRESH
495
+ @screen.erase
496
+ @screen.refresh
497
+ else
498
+ CDK.Beep
499
+ end
500
+ end
501
+
502
+ # Do we need to redraw the screen?
503
+ if refresh
504
+ self.drawInfo
505
+ end
506
+ end
507
+ end
508
+
509
+ # This searches the document looking for the given word.
510
+ def getAndStorePattern(screen)
511
+ temp = ''
512
+
513
+ # Check the direction.
514
+ if @search_direction == CDK::VIEWER::UP
515
+ temp = '</5>Search Up : <!5>'
516
+ else
517
+ temp = '</5>Search Down: <!5>'
518
+ end
519
+
520
+ # Pop up the entry field.
521
+ get_pattern = CDK::ENTRY.new(screen, CDK::CENTER, CDK::CENTER,
522
+ '', label, Ncurses.COLOR_PAIR(5) | Ncurses::A_BOLD,
523
+ '.' | Ncurses.COLOR_PAIR(5) | Ncurses::A_BOLD,
524
+ :MIXED, 10, 0, 256, true, false)
525
+
526
+ # Is there an old search pattern?
527
+ if @search_pattern.size != 0
528
+ get_pattern.set(@search_pattern, get_pattern.min, get_pattern.max,
529
+ get_pattern.box)
530
+ end
531
+
532
+ # Activate this baby.
533
+ list = get_pattern.activate([])
534
+
535
+ # Save teh list.
536
+ if list.size != 0
537
+ @search_pattern = list
538
+ end
539
+
540
+ # Clean up.
541
+ get_pattern.destroy
542
+ end
543
+
544
+ # This searches for a line containing the word and realigns the value on
545
+ # the screen.
546
+ def searchForWord(pattern, direction)
547
+ found = false
548
+
549
+ # If the pattern is empty then return.
550
+ if pattern.size != 0
551
+ if direction == CDK::VIEWER::DOWN
552
+ # Start looking from 'here' down.
553
+ x = @current_top + 1
554
+ while !found && x < @list_size
555
+ pos = 0
556
+ y = 0
557
+ while y < @list[x].size
558
+ plain_char = CDK.CharOf(@list[x][y])
559
+
560
+ pos += 1
561
+ if @CDK.CharOf(pattern[pos-1]) != plain_char
562
+ y -= (pos - 1)
563
+ pos = 0
564
+ elsif pos == pattern.size
565
+ @current_top = [x, @max_top_line].min
566
+ @left_char = if y < @box_width then 0 else @max_left_char end
567
+ found = true
568
+ break
569
+ end
570
+ y += 1
571
+ end
572
+ x += 1
573
+ end
574
+ else
575
+ # Start looking from 'here' up.
576
+ x = @current_top - 1
577
+ while ! found && x >= 0
578
+ y = 0
579
+ pos = 0
580
+ while y < @list[x].size
581
+ plain_char = CDK.CharOf(@list[x][y])
582
+
583
+ pos += 1
584
+ if CDK.CharOf(pattern[pos-1]) != plain_char
585
+ y -= (pos - 1)
586
+ pos = 0
587
+ elsif pos == pattern.size
588
+ @current_top = x
589
+ @left_char = if y < @box_width then 0 else @max_left_char end
590
+ found = true
591
+ break
592
+ end
593
+ end
594
+ end
595
+ end
596
+ end
597
+ return found
598
+ end
599
+
600
+ # This allows us to 'jump' to a given line in the file.
601
+ def jumpToLine
602
+ newline = CDK::SCALE.new(@screen, CDK::CENTER, CDK::CENTER,
603
+ '<C>Jump To Line', '</5>Line :', Ncurses::A_BOLD,
604
+ @list_size.size + 1, @current_top + 1, 0, @max_top_line + 1,
605
+ 1, 10, true, true)
606
+ line = newline.activate([])
607
+ newline.destroy
608
+ return line - 1
609
+ end
610
+
611
+ # This pops a little message up on the screen.
612
+ def popUpLabel(mesg)
613
+ # Set up variables.
614
+ label = CDK::LABEL.new(@screen, CDK::CENTER, CDK::CENTER,
615
+ mesg, mesg.size, true, false)
616
+
617
+ # Draw the label and wait.
618
+ label.draw(true)
619
+ label.getch([])
620
+
621
+ # Clean up.
622
+ label.destroy
623
+ end
624
+
625
+ # This moves the viewer field to the given location.
626
+ # Inherited
627
+ # def move(xplace, yplace, relative, refresh_flag)
628
+ # end
629
+
630
+ # This function draws the viewer widget.
631
+ def draw(box)
632
+ # Do we need to draw in the shadow?
633
+ unless @shadow_win.nil?
634
+ Draw.drawShadow(@shadow_win)
635
+ end
636
+
637
+ # Box it if it was asked for.
638
+ if box
639
+ Draw.drawObjBox(@win, self)
640
+ @win.wrefresh
641
+ end
642
+
643
+ # Draw the info in the viewer.
644
+ self.drawInfo
645
+ end
646
+
647
+ # This redraws the viewer buttons.
648
+ def drawButtons
649
+ # No buttons, no drawing
650
+ if @button_count == 0
651
+ return
652
+ end
653
+
654
+ # Redraw the buttons.
655
+ (0...@button_count).each do |x|
656
+ Draw.writeChtype(@win, @button_pos[x], @box_height - 2,
657
+ @button[x], CDK::HORIZONTAL, 0, @button_len[x])
658
+ end
659
+
660
+ # Highlight the current button.
661
+ (0...@button_len[@current_button]).each do |x|
662
+ # Strip the character of any extra attributes.
663
+ character = CDK.CharOf(@button[@current_button][x])
664
+
665
+ # Add the character into the window.
666
+ @win.mvwaddch(@box_height - 2, @button_pos[@current_button] + x,
667
+ character.ord | @button_highlight)
668
+ end
669
+
670
+ # Refresh the window.
671
+ @win.wrefresh
672
+ end
673
+
674
+ # This sets the background attribute of the widget.
675
+ def setBKattr(attrib)
676
+ @win.wbkgd(attrib)
677
+ end
678
+
679
+ def destroyInfo
680
+ @list = []
681
+ @list_pos = []
682
+ @list_len = []
683
+ end
684
+
685
+ # This function destroys the viewer widget.
686
+ def destroy
687
+ self.destroyInfo
688
+
689
+ self.cleanTitle
690
+
691
+ # Clean up the windows.
692
+ CDK.deleteCursesWindow(@shadow_win)
693
+ CDK.deleteCursesWindow(@win)
694
+
695
+ # Clean the key bindings.
696
+ self.cleanBindings(:VIEWER)
697
+
698
+ # Unregister this object.
699
+ CDK::SCREEN.unregister(:VIEWER, self)
700
+ end
701
+
702
+ # This function erases the viewer widget from the screen.
703
+ def erase
704
+ if self.validCDKObject
705
+ CDK.eraseCursesWindow(@win)
706
+ CDK.eraseCursesWindow(@shadow_win)
707
+ end
708
+ end
709
+
710
+ # This draws the viewer info lines.
711
+ def drawInfo
712
+ temp = ''
713
+ line_adjust = false
714
+
715
+ # Clear the window.
716
+ @win.werase
717
+
718
+ self.drawTitle(@win)
719
+
720
+ # Draw in the current line at the top.
721
+ if @show_line_info == true
722
+ # Set up the info line and draw it.
723
+ if @in_progress
724
+ temp = 'processing...'
725
+ elsif @list_size != 0
726
+ temp = '%d/%d %2.0f%%' % [@current_top + 1, @list_size,
727
+ ((1.0 * @current_top + 1) / (@list_size)) * 100]
728
+ else
729
+ temp = '%d/%d %2.0f%%' % [0, 0, 0.0]
730
+ end
731
+
732
+ # The list_adjust variable tells us if we have to shift down one line
733
+ # because the person asked for the line X of Y line at the top of the
734
+ # screen. We only want to set this to true if they asked for the info
735
+ # line and there is no title or if the two items overlap.
736
+ if @title_lines == '' || @title_pos[0] < temp.size + 2
737
+ list_adjust = true
738
+ end
739
+ Draw.writeChar(@win, 1,
740
+ if list_adjust then @title_lines else 0 end + 1,
741
+ temp, CDK::HORIZONTAL, 0, temp.size)
742
+ end
743
+
744
+ # Determine the last line to draw.
745
+ last_line = [@list_size, @view_size].min
746
+ last_line -= if list_adjust then 1 else 0 end
747
+
748
+ # Redraw the list.
749
+ (0...last_line).each do |x|
750
+ if @current_top + x < @list_size
751
+ screen_pos = @list_pos[@current_top + x] + 1 - @left_char
752
+
753
+ Draw.writeChtype(@win,
754
+ if screen_pos >= 0 then screen_pos else 1 end,
755
+ x + @title_lines + if list_adjust then 1 else 0 end + 1,
756
+ @list[x + @current_top], CDK::HORIZONTAL,
757
+ if screen_pos >= 0
758
+ then 0
759
+ else @left_char - @list_pos[@current_top + x]
760
+ end,
761
+ @list_len[x + @current_top])
762
+ end
763
+ end
764
+
765
+ # Box it if we have to.
766
+ if @box
767
+ Draw.drawObjBox(@win, self)
768
+ @win.wrefresh
769
+ end
770
+
771
+ # Draw the separation line.
772
+ if @button_count > 0
773
+ boxattr = @BXAttr
774
+
775
+ (1..@box_width).each do |x|
776
+ @win.mvwaddch(@box_height - 3, x, @HZChar | boxattr)
777
+ end
778
+
779
+ @win.mvwaddch(@box_height - 3, 0, Ncurses::ACS_LTEE | boxattr)
780
+ @win.mvwaddch(@box_height - 3, @win.getmaxx - 1,
781
+ Ncurses::ACS_RTEE | boxattr)
782
+ end
783
+
784
+ # Draw the buttons. This will call refresh on the viewer win.
785
+ self.drawButtons
786
+ end
787
+
788
+ # The list_size may be negative, to assign no definite limit.
789
+ def createList(list_size)
790
+ status = false
791
+
792
+ self.destroyInfo
793
+
794
+ if list_size >= 0
795
+ status = true
796
+
797
+ @list = []
798
+ @list_pos = []
799
+ @list_len = []
800
+ end
801
+ return status
802
+ end
803
+
804
+ def position
805
+ super(@win)
806
+ end
807
+
808
+ def object_type
809
+ :VIEWER
810
+ end
811
+ end
812
+ end