cheri 0.0.4 → 0.0.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/README +10 -14
- data/lib/cheri/builder/connecter.rb +1 -1
- data/lib/cheri/builder/context.rb +5 -0
- data/lib/cheri/builder/swing/connecter.rb +5 -2
- data/lib/cheri/cheri.rb +4 -2
- data/lib/cheri/explorer/explorer.rb +80 -29
- data/lib/cheri/image/Back24.gif +0 -0
- data/lib/cheri/image/Forward24.gif +0 -0
- data/lib/cheri/jruby/explorer/dialogs.rb +32 -16
- data/lib/cheri/jruby/explorer/explorer.rb +294 -101
- data/lib/cheri/jruby/explorer/viewer.rb +12 -4
- data/lib/cheri/jruby/explorer/viewers.rb +161 -30
- metadata +4 -2
data/README
CHANGED
@@ -6,7 +6,7 @@ based on the framework, as well as a builder-builder tool for easily creating
|
|
6
6
|
simple builders. Cheri also comes with a demo application, Cheri::JRuby::Explorer,
|
7
7
|
that is built using two of the supplied builders (Cheri::Swing and Cheri::Html).
|
8
8
|
|
9
|
-
This version (0.0.
|
9
|
+
This version (0.0.5) is an early beta release. Some features are not yet fully
|
10
10
|
developed, in particular the HTML/XML components. On the other hand, Cheri::Swing,
|
11
11
|
which is the successor to JRBuilder (http://www2.webng.com/bdortch/jrbuilder), is
|
12
12
|
relatively mature, in an adolescent sort of way, though many features could be added.
|
@@ -40,8 +40,13 @@ Cheri gem):
|
|
40
40
|
|
41
41
|
Cheri::JRuby::Explorer.run
|
42
42
|
|
43
|
+
Alternatively, you can load and run it in one step:
|
44
|
+
|
45
|
+
require 'rubygems'
|
46
|
+
require 'cheri/cjx'
|
47
|
+
|
43
48
|
This will take several seconds to load and start -- performance will be one area
|
44
|
-
of improvement for versions 0.0.
|
49
|
+
of improvement for versions 0.0.6 and beyond. Once it loads, it should be fairly
|
45
50
|
clear what to do.
|
46
51
|
|
47
52
|
Some known issues:
|
@@ -49,22 +54,13 @@ Some known issues:
|
|
49
54
|
* Browsing the class hierarchy is very slow right now -- this actually slowed down
|
50
55
|
in the past couple of days when I switched from HTML to straight Swing layout, the
|
51
56
|
opposite of what I expected to happen.
|
52
|
-
|
53
|
-
* ObjectSpace searches that return large numbers of objects sometimes result in a
|
54
|
-
NullPointerException (JList seems to get overwhelmed), requiring a restart of
|
55
|
-
CJX. I had a fix in that did a GC on the target instance before each search,
|
56
|
-
which seemed to help, but also seemed a little extreme. This will be a search
|
57
|
-
option in 0.0.5.
|
58
|
-
|
57
|
+
|
59
58
|
* There are lots of layout issues; neither HTML (JEditorPane) nor BoxLayout provide
|
60
59
|
exactly what I'm looking for. Will probably have to bite the bullet and go to
|
61
60
|
GridBagLayout. Ugh.
|
62
|
-
|
63
|
-
* Tab management (and navigation in general) is not yet quite right.
|
64
|
-
Will have history/back buttons and better tab management in 0.0.5.
|
65
|
-
|
61
|
+
|
66
62
|
* Global variables are currently shown, um, globally, when many of them should be shown
|
67
|
-
per thread. This will be fixed in 0.0.
|
63
|
+
per thread. This will be fixed in 0.0.6, which will include a Thread section with
|
68
64
|
other goodies as well (thread-local vars, status, etc.).
|
69
65
|
|
70
66
|
To install the CJX DRb server component in an instance (assuming the Cheri gem is
|
@@ -81,7 +81,7 @@ class TypeConnecter
|
|
81
81
|
t = @t
|
82
82
|
bld_anc = (class<<builder.object;self;end).ancestors
|
83
83
|
anc ||= (class<<obj;self;end).ancestors
|
84
|
-
key = [bld_anc,anc
|
84
|
+
key = [sym,bld_anc,anc]
|
85
85
|
if (ctr = @c[key])
|
86
86
|
return ctr.prepare(ctx,builder,obj,sym,props)
|
87
87
|
end
|
@@ -557,6 +557,11 @@ class Context
|
|
557
557
|
# alias_method :check, :ck
|
558
558
|
#
|
559
559
|
|
560
|
+
# Overrides the default Object#inspect to prevent mind-boggling circular displays in IRB.
|
561
|
+
def inspect
|
562
|
+
"#<#{self.class}:instance>"
|
563
|
+
end
|
564
|
+
|
560
565
|
# We want to prevent built objects passed as parameters from
|
561
566
|
# being dynamically connected, since presumably the method/ctor
|
562
567
|
# being called will do whatever is needed (except for cherify,
|
@@ -28,6 +28,9 @@ module Swing
|
|
28
28
|
|
29
29
|
# note: inherits connection types from AWTConnecter
|
30
30
|
SwingConnecter = Cheri::Builder::TypeConnecter.new(Cheri::AWT::AWTConnecter) do
|
31
|
+
jver = ENV_JAVA['java.version']
|
32
|
+
Java5 = String === jver && jver >= '1.5'
|
33
|
+
Java6 = String === jver && jver >= '1.6'
|
31
34
|
S = java.lang.String.new ''
|
32
35
|
TreePath = javax.swing.tree.TreePath
|
33
36
|
|
@@ -81,13 +84,13 @@ SwingConnecter = Cheri::Builder::TypeConnecter.new(Cheri::AWT::AWTConnecter) do
|
|
81
84
|
# TODO: close button (:default or user JButton)
|
82
85
|
connect java.awt.Component do |pane,cmp,sym,props|
|
83
86
|
if props
|
84
|
-
if (tc = props[:tab])
|
87
|
+
if Java6 && (tc = props[:tab])
|
85
88
|
pane.addTab(S,cmp)
|
86
89
|
i = pane.indexOfComponent(cmp)
|
87
90
|
pane.setTabComponentAt(i,tc)
|
88
91
|
# TODO: tooltip allowed for custom tab?
|
89
92
|
else
|
90
|
-
title = props[:title] || cmp.name ||
|
93
|
+
title = props[:title] || cmp.name || S
|
91
94
|
icon = props[:icon]
|
92
95
|
tooltip = props[:tooltip]
|
93
96
|
pane.addTab(title,icon,cmp,tooltip)
|
data/lib/cheri/cheri.rb
CHANGED
@@ -29,10 +29,12 @@ module Cheri
|
|
29
29
|
module VERSION #:nodoc:
|
30
30
|
MAJOR = 0
|
31
31
|
MINOR = 0
|
32
|
-
TINY =
|
32
|
+
TINY = 5
|
33
33
|
STRING = [MAJOR, MINOR, TINY].join('.').freeze
|
34
34
|
end
|
35
|
-
|
35
|
+
#:stopdoc:
|
36
|
+
PathExp = Regexp.new "cheri-#{VERSION::STRING}\\/lib$"
|
37
|
+
#:startdoc:
|
36
38
|
class CheriException < StandardError; end
|
37
39
|
# global threadsafe; set if all Cheri module instances in a system
|
38
40
|
# must be threadsafe
|
@@ -79,6 +79,9 @@ module Explorer
|
|
79
79
|
end
|
80
80
|
|
81
81
|
class ObjectRec
|
82
|
+
# TODO: make this configurable (or settable in search dialog)
|
83
|
+
MaxDataLength = 100000
|
84
|
+
|
82
85
|
def initialize(obj)
|
83
86
|
@z = obj.class.to_s rescue nil
|
84
87
|
@i = obj.__id__ rescue nil
|
@@ -95,6 +98,8 @@ class ObjectRec
|
|
95
98
|
end
|
96
99
|
@u = (obj.superclass.to_s rescue nil) if obj.respond_to?(:superclass)
|
97
100
|
@s = obj.inspect rescue nil
|
101
|
+
# we're going allow a maximum of ~ 64K for value
|
102
|
+
@s = @s[0,MaxDataLength] << '...' if @s && @s.length > MaxDataLength
|
98
103
|
end
|
99
104
|
def clazz
|
100
105
|
@z
|
@@ -186,7 +191,7 @@ class NameValue
|
|
186
191
|
raise Cheri.type_error(name,String) unless String === name
|
187
192
|
@n = name
|
188
193
|
@i = value.__id__ rescue '?'
|
189
|
-
@v = String === value ? value[0,
|
194
|
+
@v = String === value ? value[0,128] : (value.to_s[0,128] rescue '?')
|
190
195
|
end
|
191
196
|
def name
|
192
197
|
@n
|
@@ -229,6 +234,7 @@ class NameTypeValue < NameValue
|
|
229
234
|
end #NameTypeValue
|
230
235
|
|
231
236
|
class SearchArgs
|
237
|
+
attr :gc, true
|
232
238
|
def initialize(clazz,vars=nil,any=nil)
|
233
239
|
raise Cheri.type_error(clazz,String) unless String === clazz
|
234
240
|
raise ArgumentError,"Invalid class "+ clazz unless /^([A-Z])((\w|::[A-Z])*)$/.match clazz
|
@@ -237,7 +243,7 @@ class SearchArgs
|
|
237
243
|
raise Cheri.type_error(vars,Array) unless Array === vars
|
238
244
|
vars.each do |v|
|
239
245
|
raise Cheri.type_error(v,SearchNameValue) unless SearchNameValue === v
|
240
|
-
raise Cheri.type_error(v.name,Symbol)
|
246
|
+
raise Cheri.type_error(v.name,Symbol) if v.name && !(Symbol === v.name)
|
241
247
|
end
|
242
248
|
@v = vars
|
243
249
|
@a = !(any == nil || any == false)
|
@@ -402,7 +408,9 @@ class RubyExplorer
|
|
402
408
|
def module_methods(name,id=nil)
|
403
409
|
if id && defined?ObjectSpace
|
404
410
|
raise Cheri.type_error(id,Fixnum) unless Fixnum === id
|
405
|
-
|
411
|
+
# doing this in two steps to work around JRuby bug (JRUBY-1125)
|
412
|
+
mod = ObjectSpace._id2ref(id)
|
413
|
+
if Module === mod
|
406
414
|
return MethodRec.new(mod)
|
407
415
|
end
|
408
416
|
elsif name
|
@@ -420,7 +428,9 @@ class RubyExplorer
|
|
420
428
|
def object(id)
|
421
429
|
return unless id && defined?ObjectSpace
|
422
430
|
raise Cheri.type_error(id,Fixnum) unless Fixnum === id
|
423
|
-
|
431
|
+
# doing this in two steps to work around JRuby bug (JRUBY-1125)
|
432
|
+
obj = ObjectSpace._id2ref(id)
|
433
|
+
if obj && !(Fixnum === obj)
|
424
434
|
if Module === obj && (name = obj.name rescue nil)
|
425
435
|
if (ix = name.rindex('::'))
|
426
436
|
parent = name[0,ix]
|
@@ -440,18 +450,22 @@ class RubyExplorer
|
|
440
450
|
def object_methods(id)
|
441
451
|
return unless id && defined?ObjectSpace
|
442
452
|
raise Cheri.type_error(id,Fixnum) unless Fixnum === id
|
443
|
-
|
453
|
+
# doing this in two steps to work around JRuby bug (JRUBY-1125)
|
454
|
+
obj = ObjectSpace._id2ref(id)
|
455
|
+
if obj && !(Fixnum === obj)
|
444
456
|
return MethodRec.new(obj)
|
445
457
|
end
|
446
458
|
end
|
447
459
|
|
448
|
-
def simple_value(id)
|
460
|
+
def simple_value(id,maxlen=80)
|
449
461
|
return unless id && defined?ObjectSpace
|
450
462
|
raise Cheri.type_error(id,Fixnum) unless Fixnum === id
|
451
|
-
|
452
|
-
|
463
|
+
# doing this in two steps to work around JRuby bug (JRUBY-1125)
|
464
|
+
obj = ObjectSpace._id2ref(id)
|
465
|
+
if obj && !(Fixnum === obj)
|
466
|
+
obj.to_s[0,maxlen] rescue 'Unreadable'
|
453
467
|
else
|
454
|
-
|
468
|
+
nil
|
455
469
|
end
|
456
470
|
end
|
457
471
|
|
@@ -463,30 +477,67 @@ class RubyExplorer
|
|
463
477
|
# make sure we don't have anything executable before we eval it
|
464
478
|
raise ArgumentError,"Invalid class "+ sclazz unless /^([A-Z])((\w|::[A-Z])*)$/.match sclazz
|
465
479
|
if Module === (clazz = (eval("::#{sclazz}") rescue nil))
|
466
|
-
|
480
|
+
GC.start if sargs.gc
|
467
481
|
result = []
|
468
|
-
vars = sargs.vars
|
469
|
-
|
470
|
-
|
471
|
-
|
472
|
-
|
473
|
-
|
474
|
-
|
475
|
-
|
476
|
-
|
477
|
-
|
478
|
-
|
479
|
-
|
480
|
-
|
481
|
-
|
482
|
-
|
482
|
+
if (vars = sargs.vars) && !vars.empty?
|
483
|
+
# just supporting one var name and/or value for now
|
484
|
+
sname = vars[0].name
|
485
|
+
raise ArgumentError,"Invalid instance variable" if sname && !(Symbol === sname)
|
486
|
+
sval = vars[0].value
|
487
|
+
sval = nil if String === sval && sval.empty?
|
488
|
+
rx = Regexp === sval
|
489
|
+
else
|
490
|
+
sname = nil
|
491
|
+
sval = nil
|
492
|
+
end
|
493
|
+
if sname && sval
|
494
|
+
ObjectSpace.each_object(clazz) do |o|
|
495
|
+
if Fixnum === (id = o.__id__ rescue nil) &&
|
496
|
+
#(o.respond_to?(:instance_variable_get) rescue nil) &&
|
497
|
+
(iv = o.instance_variable_get(sname) rescue nil) &&
|
498
|
+
(String === iv || String === (iv = iv.to_s rescue nil)) &&
|
499
|
+
(rx ? (iv =~ sval rescue nil) : (iv.index(sval) rescue nil))
|
500
|
+
result << id
|
501
|
+
end
|
502
|
+
end
|
503
|
+
elsif sname
|
504
|
+
sname = sname.to_s
|
505
|
+
ObjectSpace.each_object(clazz) do |o|
|
506
|
+
if Fixnum === (id = o.__id__ rescue nil) &&
|
507
|
+
#(o.respond_to?(:instance_variables) rescue nil) &&
|
508
|
+
Array === (ivs = o.instance_variables rescue nil) &&
|
509
|
+
(ivs.include?(sname) rescue nil)
|
510
|
+
result << id
|
511
|
+
end
|
512
|
+
end
|
513
|
+
elsif sval
|
514
|
+
# note: _not_ calling inspect here to avoid circular reference trap;
|
515
|
+
# examining (potentially) each instance var instead
|
516
|
+
ObjectSpace.each_object(clazz) do |o|
|
517
|
+
if Fixnum === (id = o.__id__ rescue nil)
|
518
|
+
if (String === (os = o) || String === (os = o.to_s rescue nil)) &&
|
519
|
+
(rx ? (os =~ sval rescue nil) : (os.index(sval) rescue nil))
|
520
|
+
result << id
|
521
|
+
elsif Array === (ivs = o.instance_variables rescue nil)
|
522
|
+
hit = nil
|
523
|
+
ivs.each do |ivn|
|
524
|
+
if (iv = o.instance_variable_get(ivn.to_sym) rescue nil) &&
|
525
|
+
(String === iv || String === (iv = iv.to_s rescue nil)) &&
|
526
|
+
(rx ? (iv =~ sval rescue nil) : (iv.index(sval) rescue nil))
|
527
|
+
result << id unless hit
|
528
|
+
hit = true
|
529
|
+
# this doesn't appear to be breaking?
|
530
|
+
break # TODO: check for LocalJumpError
|
483
531
|
end
|
484
532
|
end
|
485
533
|
end
|
486
|
-
|
487
|
-
|
488
|
-
|
489
|
-
|
534
|
+
end
|
535
|
+
end
|
536
|
+
else
|
537
|
+
ObjectSpace.each_object(clazz) do |o|
|
538
|
+
if Fixnum === (id = o.__id__ rescue nil)
|
539
|
+
result << id
|
540
|
+
end
|
490
541
|
end
|
491
542
|
end
|
492
543
|
result
|
Binary file
|
Binary file
|
@@ -165,8 +165,6 @@ class SearchDialog
|
|
165
165
|
@object_id = text_field do
|
166
166
|
columns 16
|
167
167
|
fixed_size 100,24
|
168
|
-
#maximum_size dimension(100,24)
|
169
|
-
#minimum_size dimension(100,24)
|
170
168
|
end
|
171
169
|
y_glue
|
172
170
|
end
|
@@ -182,6 +180,7 @@ class SearchDialog
|
|
182
180
|
'Search Error', JOptionPane::ERROR_MESSAGE)
|
183
181
|
else
|
184
182
|
@dialog.visible = false
|
183
|
+
@object_id.text = ''
|
185
184
|
@main.new_find(@instances[@instance_list.selected_index],id)
|
186
185
|
end
|
187
186
|
end
|
@@ -192,11 +191,12 @@ class SearchDialog
|
|
192
191
|
|
193
192
|
y_glue
|
194
193
|
|
195
|
-
|
194
|
+
y_panel do
|
196
195
|
compound_border(
|
197
196
|
titled_border('Search for instances by type and optional variable/value') { etched_border :LOWERED },
|
198
197
|
empty_border(4,8,4,8)
|
199
198
|
)
|
199
|
+
x_panel do
|
200
200
|
y_box do
|
201
201
|
y_glue
|
202
202
|
label 'Class or Module:'
|
@@ -217,22 +217,16 @@ class SearchDialog
|
|
217
217
|
@clazz = text_field do
|
218
218
|
columns 20
|
219
219
|
fixed_size 200,24
|
220
|
-
#maximum_size dimension(200,24)
|
221
|
-
#minimum_size dimension(200,24)
|
222
220
|
end
|
223
221
|
y_glue
|
224
222
|
@name1 = text_field do
|
225
223
|
columns 20
|
226
224
|
fixed_size 200,24
|
227
|
-
#maximum_size dimension(200,24)
|
228
|
-
#minimum_size dimension(200,24)
|
229
225
|
end
|
230
226
|
y_glue
|
231
227
|
@value1 = text_field do
|
232
228
|
columns 20
|
233
229
|
fixed_size 200,24
|
234
|
-
#maximum_size dimension(200,24)
|
235
|
-
#minimum_size dimension(200,24)
|
236
230
|
end
|
237
231
|
y_glue
|
238
232
|
end
|
@@ -253,24 +247,38 @@ class SearchDialog
|
|
253
247
|
elsif name && name !~ /^([A-Za-z_])(\w*)$/
|
254
248
|
JOptionPane.show_message_dialog(@dialog,"Invalid variable name, please re-enter",
|
255
249
|
'Search Error', JOptionPane::ERROR_MESSAGE)
|
256
|
-
elsif value && !name && !value.empty?
|
257
|
-
JOptionPane.show_message_dialog(@dialog,"Please enter a variable name (or omit value)",
|
258
|
-
'Search Error', JOptionPane::ERROR_MESSAGE)
|
259
250
|
else
|
260
|
-
|
261
|
-
|
251
|
+
if value && value.strip.length != value.length
|
252
|
+
rsp = JOptionPane.show_confirm_dialog(@main_frame,
|
253
|
+
"Value contains leading/trailing whitespace -- continue?")
|
254
|
+
else
|
255
|
+
rsp = nil
|
256
|
+
end
|
257
|
+
unless rsp && rsp != JOptionPane::YES_OPTION
|
258
|
+
@dialog.visible = false
|
259
|
+
gc = @gc.selected
|
260
|
+
reset_fields
|
261
|
+
@main.new_search(@instances[@instance_list.selected_index],clazz,name,value,gc)
|
262
|
+
end
|
262
263
|
end
|
263
264
|
end
|
264
265
|
end
|
265
266
|
end
|
267
|
+
end
|
268
|
+
x_panel do
|
269
|
+
@gc = check_box 'GC target instance before search'
|
270
|
+
end
|
266
271
|
end
|
267
272
|
y_glue
|
273
|
+
x_box do
|
274
|
+
x_glue
|
268
275
|
button 'Cancel' do
|
269
276
|
on_click do
|
270
277
|
@dialog.visible = false
|
271
278
|
end
|
272
279
|
end
|
273
|
-
|
280
|
+
x_glue
|
281
|
+
end
|
274
282
|
y_glue
|
275
283
|
end
|
276
284
|
|
@@ -285,6 +293,14 @@ class SearchDialog
|
|
285
293
|
val
|
286
294
|
end
|
287
295
|
|
296
|
+
def reset_fields
|
297
|
+
@clazz.text = ''
|
298
|
+
@name1.text = ''
|
299
|
+
@value1.text = ''
|
300
|
+
@gc.selected = false
|
301
|
+
end
|
302
|
+
private :reset_fields
|
303
|
+
|
288
304
|
def value
|
289
305
|
@dialog
|
290
306
|
end
|
@@ -345,7 +361,7 @@ class AboutDialog
|
|
345
361
|
table(:width=>'97%') {
|
346
362
|
tr{td(:align=>:left) {
|
347
363
|
p 'Cheri::JRuby::Explorer (CJX) demonstrates some of the features ',
|
348
|
-
'of the Cheri builder framework, and
|
364
|
+
'of the Cheri builder framework, and may even prove useful ',
|
349
365
|
'in its own right. CJX is built using the Cheri::Swing and Cheri::Html ',
|
350
366
|
'components of the framework.'
|
351
367
|
p
|
@@ -72,6 +72,9 @@ class Main
|
|
72
72
|
SearchIcon = CJava.get_icon('Search24.gif')
|
73
73
|
RefreshIcon = CJava.get_icon('Refresh24.gif')
|
74
74
|
CloseIcon = CJava.get_icon('Delete24.gif')
|
75
|
+
# TODO: I *hate* these next two -- find replacements!
|
76
|
+
NextIcon = CJava.get_icon('Forward24.gif')
|
77
|
+
PrevIcon = CJava.get_icon('Back24.gif')
|
75
78
|
ClassIcon = CJava.get_icon('class_16x16.png')
|
76
79
|
ModuleIcon = CJava.get_icon('mod_tree.png')
|
77
80
|
Viewers = Cheri::JRuby::Explorer
|
@@ -106,9 +109,10 @@ class Main
|
|
106
109
|
@instances = {}
|
107
110
|
@instance_listeners = []
|
108
111
|
@main_tabs = {}
|
109
|
-
@
|
112
|
+
@result_tabs = {}
|
113
|
+
@main_tab_history = []
|
110
114
|
@main_tabs[:global] = {}
|
111
|
-
@
|
115
|
+
@result_tabs[:global] = {}
|
112
116
|
@local_instance = JRubyInstance.new(RubyExplorer.new,'Local','local')
|
113
117
|
add_instance(@local_instance)
|
114
118
|
end
|
@@ -122,14 +126,14 @@ class Main
|
|
122
126
|
@main_frame.set_location(Math.max(0,(bounds.width - 800)/2), Math.max(0,(bounds.height - 760)/2))
|
123
127
|
@main_frame.show
|
124
128
|
@main_frame.to_front
|
125
|
-
sleep
|
129
|
+
sleep 1.5
|
126
130
|
@main_tree.selection_row = 0
|
127
131
|
@main_frame.content_pane.remove(splash_screen)
|
128
132
|
@main_menu.visible = true
|
129
133
|
@main_tool_bar.visible = true
|
130
134
|
@main_panel.visible = true
|
131
135
|
@footer_panel.visible = true
|
132
|
-
@
|
136
|
+
@result_tab_pane.visible = false
|
133
137
|
end
|
134
138
|
|
135
139
|
def release_resources
|
@@ -157,7 +161,7 @@ class Main
|
|
157
161
|
right_pane do
|
158
162
|
right_splitter do
|
159
163
|
main_tab_pane
|
160
|
-
|
164
|
+
result_tab_pane
|
161
165
|
end
|
162
166
|
end
|
163
167
|
end
|
@@ -212,10 +216,10 @@ class Main
|
|
212
216
|
def view_menu(&block)
|
213
217
|
@view_menu ||= menu 'View' do |mn|
|
214
218
|
mnemonic :VK_V
|
215
|
-
@
|
219
|
+
@results_select = check_box_menu_item 'Search Results pane' do
|
216
220
|
selected true
|
217
221
|
on_click do |e|
|
218
|
-
if (@
|
222
|
+
if (@result_tab_pane.visible = e.source.selected = !@result_tab_pane.visible)
|
219
223
|
adjust_right_splitter
|
220
224
|
end
|
221
225
|
end
|
@@ -264,7 +268,12 @@ class Main
|
|
264
268
|
on_click do
|
265
269
|
show_search_dialog
|
266
270
|
end
|
267
|
-
|
271
|
+
end
|
272
|
+
menu_item 'Repeat last search' do
|
273
|
+
mnemonic :VK_R
|
274
|
+
on_click do
|
275
|
+
repeat_search
|
276
|
+
end
|
268
277
|
end
|
269
278
|
end
|
270
279
|
cheri_yield(@search_menu,&block) if block
|
@@ -304,9 +313,24 @@ class Main
|
|
304
313
|
show_search_dialog
|
305
314
|
end
|
306
315
|
end
|
307
|
-
button FindAgainIcon
|
308
|
-
|
316
|
+
button FindAgainIcon do
|
317
|
+
tool_tip_text 'Repeat last search'
|
318
|
+
on_click do
|
319
|
+
repeat_search
|
320
|
+
end
|
321
|
+
end
|
322
|
+
button SearchIcon do
|
323
|
+
tool_tip_text "We don't know what this does yet"
|
324
|
+
end
|
309
325
|
x_glue
|
326
|
+
button PrevIcon do
|
327
|
+
tool_tip_text 'Previous tab view'
|
328
|
+
on_click {prev_view}
|
329
|
+
end
|
330
|
+
button NextIcon do
|
331
|
+
tool_tip_text 'Next tab view'
|
332
|
+
on_click {next_view}
|
333
|
+
end
|
310
334
|
button CloseActiveIcon do
|
311
335
|
tool_tip_text 'Close active view'
|
312
336
|
on_click do
|
@@ -372,15 +396,15 @@ class Main
|
|
372
396
|
@main_tab_pane
|
373
397
|
end
|
374
398
|
|
375
|
-
def
|
376
|
-
unless @
|
377
|
-
@
|
399
|
+
def result_tab_pane(&block)
|
400
|
+
unless @result_tab_pane
|
401
|
+
@result_tab_pane = tabbed_pane do
|
378
402
|
align :LEFT
|
379
403
|
end
|
380
|
-
@
|
404
|
+
@result_tab_pane.extend TabbedPaneMethods
|
381
405
|
end
|
382
|
-
cheri_yield(@
|
383
|
-
@
|
406
|
+
cheri_yield(@result_tab_pane,&block) if block
|
407
|
+
@result_tab_pane
|
384
408
|
end
|
385
409
|
|
386
410
|
def main_panel(&block)
|
@@ -469,32 +493,51 @@ class Main
|
|
469
493
|
tabs = main_tab_pane
|
470
494
|
unless tabs.include?(view)
|
471
495
|
set_view_viewer(view,viewer)
|
472
|
-
instance = viewer.instance
|
496
|
+
if instance = viewer.instance
|
497
|
+
tab_group = instance.__id__
|
498
|
+
else
|
499
|
+
tab_group = :global
|
500
|
+
end
|
473
501
|
ntype = viewer.type.type
|
474
502
|
tab_type = TypeTabMap[ntype] || ntype
|
475
|
-
current_viewer = @main_tabs[
|
476
|
-
if current_viewer && (
|
477
|
-
tabs
|
478
|
-
if Java6 && (tab = viewer.tab)
|
479
|
-
tabs[ix,:tab] = tab
|
480
|
-
else
|
481
|
-
tabs[ix,:title] = viewer.title_tab
|
482
|
-
tabs[ix,:icon] = viewer.icon_tab
|
483
|
-
end
|
503
|
+
current_viewer = @main_tabs[tab_group][tab_type]
|
504
|
+
if current_viewer && (index = tabs.index(current_viewer.view))
|
505
|
+
replace_view_tab(tabs,view,viewer,index)
|
484
506
|
else
|
485
|
-
|
486
|
-
if Java6 && (tab = viewer.tab)
|
487
|
-
cherify(view, :tab => tab)
|
488
|
-
else
|
489
|
-
cherify(view, :title => viewer.title_tab, :icon => viewer.icon_tab)
|
490
|
-
end
|
491
|
-
end
|
507
|
+
add_view_tab(tabs,view,viewer)
|
492
508
|
end
|
493
|
-
@main_tabs[
|
509
|
+
@main_tabs[tab_group][tab_type] = viewer
|
494
510
|
end
|
495
511
|
tabs.set_selected_component(view)
|
496
512
|
end
|
497
513
|
|
514
|
+
def add_view_tab(tabs,view,viewer)
|
515
|
+
cheri_yield tabs do
|
516
|
+
cherify(view, :tab => viewer.tab, :title => viewer.title_tab, :icon => viewer.icon_tab)
|
517
|
+
end
|
518
|
+
if tabs == @main_tab_pane
|
519
|
+
index = tabs.index(view)
|
520
|
+
@main_tab_history[index] = TabHistory.new(viewer)
|
521
|
+
end
|
522
|
+
end
|
523
|
+
|
524
|
+
def replace_view_tab(tabs,view,viewer,index)
|
525
|
+
tabs[index] = view
|
526
|
+
if Java6 && (tab = viewer.tab)
|
527
|
+
tabs[index,:tab] = tab
|
528
|
+
else
|
529
|
+
tabs[index,:title] = viewer.title_tab
|
530
|
+
tabs[index,:icon] = viewer.icon_tab
|
531
|
+
end
|
532
|
+
if tabs == @main_tab_pane
|
533
|
+
if hist = @main_tab_history[index]
|
534
|
+
hist << viewer
|
535
|
+
else
|
536
|
+
@main_tab_history[index] = TabHistory.new(viewer)
|
537
|
+
end
|
538
|
+
end
|
539
|
+
end
|
540
|
+
|
498
541
|
def prepare_for_node_expansion(node)
|
499
542
|
unless node.child_count > 0
|
500
543
|
vwr = node.user_object
|
@@ -533,6 +576,36 @@ class Main
|
|
533
576
|
view.get_client_property(:viewer)
|
534
577
|
end
|
535
578
|
|
579
|
+
def next_view
|
580
|
+
tabs = main_tab_pane
|
581
|
+
if (oldvwr = tabs.active_viewer) &&
|
582
|
+
(ix = tabs.index(oldvwr.view)) &&
|
583
|
+
(hist = @main_tab_history[ix]) &&
|
584
|
+
(newvwr = hist.next!)
|
585
|
+
replace_view(tabs,ix,newvwr)
|
586
|
+
end
|
587
|
+
end
|
588
|
+
|
589
|
+
def prev_view
|
590
|
+
tabs = main_tab_pane
|
591
|
+
if (oldvwr = tabs.active_viewer) &&
|
592
|
+
(ix = tabs.index(oldvwr.view)) &&
|
593
|
+
(hist = @main_tab_history[ix]) &&
|
594
|
+
(newvwr = hist.prev!)
|
595
|
+
replace_view(tabs,ix,newvwr)
|
596
|
+
end
|
597
|
+
end
|
598
|
+
|
599
|
+
def replace_view(tabs,index,viewer)
|
600
|
+
tabs[index] = viewer.view
|
601
|
+
if Java6 && (tab = viewer.tab)
|
602
|
+
tabs[index,:tab] = tab
|
603
|
+
else
|
604
|
+
tabs[index,:title] = viewer.title_tab
|
605
|
+
tabs[index,:icon] = viewer.icon_tab
|
606
|
+
end
|
607
|
+
end
|
608
|
+
|
536
609
|
def refresh_active_view
|
537
610
|
if (viewer = main_tab_pane.active_viewer)
|
538
611
|
viewer.refresh if viewer.respond_to?(:refresh)
|
@@ -546,29 +619,39 @@ class Main
|
|
546
619
|
end
|
547
620
|
|
548
621
|
def close_active_search_view
|
549
|
-
if (viewer =
|
550
|
-
|
622
|
+
if (viewer = result_tab_pane.active_viewer)
|
623
|
+
close_results_view(viewer)
|
551
624
|
end
|
552
625
|
end
|
553
626
|
|
554
627
|
def close_view(viewer)
|
555
628
|
view = viewer.view
|
556
|
-
main_tab_pane.
|
557
|
-
|
629
|
+
index = (tabs = main_tab_pane).index(view)
|
630
|
+
tabs.remove(view)
|
631
|
+
@main_tab_history.delete_at(index)
|
632
|
+
if instance = viewer.instance
|
633
|
+
tab_group = instance.__id__
|
634
|
+
else
|
635
|
+
tab_group = :global
|
636
|
+
end
|
558
637
|
ntype = viewer.type.type
|
559
638
|
tab_type = TypeTabMap[ntype] || ntype
|
560
|
-
@main_tabs[
|
561
|
-
@main_tabs[
|
639
|
+
@main_tabs[tab_group].delete(tab_type) if @main_tabs[tab_group][tab_type] == viewer
|
640
|
+
@main_tabs[tab_group].delete(viewer.__id__)
|
562
641
|
end
|
563
642
|
|
564
|
-
def
|
643
|
+
def close_results_view(viewer)
|
565
644
|
view = viewer.view
|
566
|
-
|
567
|
-
instance = viewer.instance
|
645
|
+
result_tab_pane.remove(view)
|
646
|
+
if instance = viewer.instance
|
647
|
+
tab_group = instance.__id__
|
648
|
+
else
|
649
|
+
tab_group = :global
|
650
|
+
end
|
568
651
|
ntype = viewer.type.type
|
569
652
|
tab_type = TypeTabMap[ntype] || ntype
|
570
|
-
@
|
571
|
-
@
|
653
|
+
@result_tabs[tab_group].delete(tab_type) if @result_tabs[tab_group][tab_type] == viewer
|
654
|
+
@result_tabs[tab_group].delete(viewer.__id__)
|
572
655
|
end
|
573
656
|
|
574
657
|
def close_views_for_instance(inst)
|
@@ -577,41 +660,39 @@ class Main
|
|
577
660
|
views.each do |view|
|
578
661
|
close_view(view_viewer(view))
|
579
662
|
end
|
580
|
-
views =
|
663
|
+
views = result_tab_pane.select {|view| view_viewer(view).instance == inst}
|
581
664
|
views.each do |view|
|
582
|
-
|
665
|
+
close_results_view(view_viewer(view))
|
583
666
|
end
|
584
667
|
end
|
585
668
|
|
586
|
-
def
|
669
|
+
def open_results_view(viewer)
|
587
670
|
view = viewer.view
|
588
|
-
tabs =
|
671
|
+
tabs = result_tab_pane
|
589
672
|
set_view_viewer(view,viewer)
|
590
|
-
instance = viewer.instance
|
673
|
+
if instance = viewer.instance
|
674
|
+
tab_group = instance.__id__
|
675
|
+
else
|
676
|
+
tab_group = :global
|
677
|
+
end
|
591
678
|
ntype = viewer.type.type
|
592
679
|
tab_type = TypeTabMap[ntype] || ntype
|
593
|
-
|
594
|
-
|
595
|
-
cherify(view, :tab => tab)
|
596
|
-
else
|
597
|
-
cherify(view, :title => viewer.title_tab, :icon => viewer.icon_tab)
|
598
|
-
end
|
599
|
-
end
|
600
|
-
@search_tabs[instance][tab_type] = viewer
|
680
|
+
add_view_tab(tabs,view,viewer)
|
681
|
+
@result_tabs[tab_group][tab_type] = viewer
|
601
682
|
tabs.set_selected_component(view)
|
602
683
|
show_search_results
|
603
684
|
end
|
604
685
|
|
605
686
|
def show_search_results
|
606
|
-
@
|
607
|
-
@
|
687
|
+
@result_tab_pane.visible = true
|
688
|
+
@results_select.selected = true
|
608
689
|
adjust_right_splitter
|
609
690
|
end
|
610
691
|
|
611
692
|
def add_instance(instance)
|
612
693
|
@instances[instance.address] = instance
|
613
|
-
@main_tabs[instance] = {}
|
614
|
-
@
|
694
|
+
@main_tabs[instance.__id__] = {}
|
695
|
+
@result_tabs[instance.__id__] = {}
|
615
696
|
@instance_listeners.each do |lst|
|
616
697
|
lst.instance_added(instance)
|
617
698
|
end
|
@@ -621,8 +702,8 @@ class Main
|
|
621
702
|
close_views_for_instance(inst)
|
622
703
|
main_tree_model.remove_node_from_parent(inst.tree_node) if inst.tree_node
|
623
704
|
@instances.delete(inst.address)
|
624
|
-
@main_tabs.delete(inst)
|
625
|
-
@
|
705
|
+
@main_tabs.delete(inst.__id__)
|
706
|
+
@result_tabs.delete(inst.__id__)
|
626
707
|
@instance_listeners.each do |lst|
|
627
708
|
lst.instance_removed(inst)
|
628
709
|
end
|
@@ -684,64 +765,137 @@ class Main
|
|
684
765
|
@connection_dialog ||= ConnectionDialog.new(self)
|
685
766
|
end
|
686
767
|
|
687
|
-
def new_search(instance,clazz,var,value)
|
768
|
+
def new_search(instance,clazz,var,value,gc=nil)
|
688
769
|
raise Cheri.type_error(clazz,RubyInstance) unless RubyInstance === instance
|
689
770
|
raise ArgumentError, "invalid class name #{clazz}" unless clazz =~ /^([A-Z])((\w|::[A-Z])*)$/
|
690
771
|
raise ArgumentError, "invalid variable name #{var}" if var && var !~ /^([A-Za-z_])(\w*)$/
|
691
|
-
if var
|
692
|
-
|
693
|
-
if value
|
694
|
-
|
695
|
-
|
696
|
-
|
697
|
-
return
|
698
|
-
end
|
699
|
-
else
|
700
|
-
val = value
|
772
|
+
var = ('@' + var).to_sym rescue nil if var
|
773
|
+
if value
|
774
|
+
if value =~ /^(\/)(.*)(\/)$/
|
775
|
+
unless (val = Regexp.new($2) rescue nil)
|
776
|
+
JOptionPane.show_message_dialog(@main_frame,"Invalid regular expression #{value}")
|
777
|
+
return
|
701
778
|
end
|
702
779
|
else
|
703
|
-
val =
|
780
|
+
val = value
|
704
781
|
end
|
782
|
+
end
|
783
|
+
if var || value
|
705
784
|
nv = Cheri::Explorer::SearchNameValue.new(var,val)
|
706
785
|
args = Cheri::Explorer::SearchArgs.new(clazz,[nv])
|
707
786
|
else
|
708
787
|
args = Cheri::Explorer::SearchArgs.new(clazz)
|
709
788
|
end
|
710
|
-
|
789
|
+
args.gc = true if gc
|
790
|
+
@last_search = [instance,args]
|
711
791
|
if (res = instance.proxy.find(args))
|
712
792
|
results = Cheri::Explorer::SearchResults.new(args,res)
|
713
793
|
vwr = viewer(:results).new(NodeTypes[:results],self,instance,results)
|
714
|
-
|
794
|
+
open_results_view(vwr)
|
715
795
|
end
|
716
796
|
end
|
717
797
|
|
718
|
-
def
|
719
|
-
if
|
720
|
-
|
721
|
-
|
722
|
-
|
723
|
-
|
724
|
-
|
725
|
-
|
726
|
-
|
727
|
-
|
728
|
-
|
729
|
-
|
730
|
-
|
731
|
-
|
732
|
-
|
733
|
-
|
734
|
-
|
735
|
-
|
736
|
-
|
737
|
-
|
738
|
-
|
798
|
+
def repeat_search
|
799
|
+
if (last = @last_search)
|
800
|
+
instance = last[0]
|
801
|
+
args = last[1]
|
802
|
+
if (res = instance.proxy.find(args))
|
803
|
+
results = Cheri::Explorer::SearchResults.new(args,res)
|
804
|
+
vwr = viewer(:results).new(NodeTypes[:results],self,instance,results)
|
805
|
+
open_results_view(vwr)
|
806
|
+
end
|
807
|
+
end
|
808
|
+
end
|
809
|
+
|
810
|
+
# def new_find(instance,id,new_tab=nil)
|
811
|
+
# if rec = instance.proxy.object(id)
|
812
|
+
# ntv = case rec.clazz
|
813
|
+
# when 'Class' : NodeTypeValue.new(Class,rec.value,rec)
|
814
|
+
# when 'Module' : NodeTypeValue.new(Module,rec.value,rec)
|
815
|
+
# else NodeTypeValue.new(:object,rec.clazz,rec)
|
816
|
+
# end
|
817
|
+
# if (clazz = viewer(ntv.type,ntv.subtype))
|
818
|
+
# vwr = clazz.new(ntv,self,instance,ntv.value)
|
819
|
+
# view = vwr.view
|
820
|
+
# set_view_viewer(view,vwr)
|
821
|
+
# tabs = main_tab_pane
|
822
|
+
# add_view_tab(tabs,view,vwr)
|
823
|
+
# @main_tabs[instance.__id__][vwr.__id__] = vwr
|
824
|
+
# tabs.set_selected_component(view)
|
825
|
+
# else
|
826
|
+
# JOptionPane.show_message_dialog(@main_frame,"Unable to display object #{id} (no viewer)")
|
827
|
+
# end
|
828
|
+
# else
|
829
|
+
# JOptionPane.show_message_dialog(@main_frame,"Unable to retrieve object #{id} (garbage-collected?)")
|
830
|
+
# end
|
831
|
+
# end
|
832
|
+
#
|
833
|
+
def show_linked_object(curvwr,id,new_tab=nil)
|
834
|
+
instance = curvwr.instance
|
835
|
+
unless rec = instance.proxy.object(id)
|
836
|
+
JOptionPane.show_message_dialog(@main_frame,"Unable to retrieve object #{id} (garbage-collected?)")
|
837
|
+
return
|
838
|
+
end
|
839
|
+
ntv = case rec.clazz
|
840
|
+
when 'Class' : NodeTypeValue.new(Class,rec.value,rec)
|
841
|
+
when 'Module' : NodeTypeValue.new(Module,rec.value,rec)
|
842
|
+
else NodeTypeValue.new(:object,rec.clazz,rec)
|
843
|
+
end
|
844
|
+
unless clazz = viewer(ntv.type,ntv.subtype)
|
845
|
+
JOptionPane.show_message_dialog(@main_frame,"Unable to display object #{id} (no viewer)")
|
846
|
+
end
|
847
|
+
vwr = clazz.new(ntv,self,instance,ntv.value)
|
848
|
+
view = vwr.view
|
849
|
+
set_view_viewer(view,vwr)
|
850
|
+
tabs = main_tab_pane
|
851
|
+
if new_tab
|
852
|
+
add_view_tab(tabs,view,vwr)
|
853
|
+
@main_tabs[instance.__id__][vwr.__id__] = vwr
|
854
|
+
else
|
855
|
+
ntype = vwr.type.type
|
856
|
+
tab_type = TypeTabMap[ntype] || ntype
|
857
|
+
current_viewer = @main_tabs[instance.__id__][tab_type]
|
858
|
+
if current_viewer && (index = tabs.index(current_viewer.view))
|
859
|
+
replace_view_tab(tabs,view,vwr,index)
|
739
860
|
else
|
740
|
-
|
861
|
+
add_view_tab(tabs,view,vwr)
|
741
862
|
end
|
863
|
+
@main_tabs[instance.__id__][tab_type] = vwr
|
864
|
+
end
|
865
|
+
tabs.set_selected_component(view)
|
866
|
+
end
|
867
|
+
|
868
|
+
def show_result_object(resvwr,id,new_tab=nil)
|
869
|
+
instance = resvwr.instance
|
870
|
+
unless rec = instance.proxy.object(id)
|
871
|
+
JOptionPane.show_message_dialog(@main_frame,"Unable to retrieve object #{id} (garbage-collected?)")
|
872
|
+
return
|
873
|
+
end
|
874
|
+
ntv = case rec.clazz
|
875
|
+
when 'Class' : NodeTypeValue.new(Class,rec.value,rec)
|
876
|
+
when 'Module' : NodeTypeValue.new(Module,rec.value,rec)
|
877
|
+
else NodeTypeValue.new(:object,rec.clazz,rec)
|
878
|
+
end
|
879
|
+
unless clazz = viewer(ntv.type,ntv.subtype)
|
880
|
+
JOptionPane.show_message_dialog(@main_frame,"Unable to display object #{id} (no viewer)")
|
881
|
+
end
|
882
|
+
vwr = clazz.new(ntv,self,instance,ntv.value)
|
883
|
+
view = vwr.view
|
884
|
+
set_view_viewer(view,vwr)
|
885
|
+
tabs = main_tab_pane
|
886
|
+
if new_tab
|
887
|
+
add_view_tab(tabs,view,vwr)
|
888
|
+
@main_tabs[instance.__id__][vwr.__id__] = vwr
|
742
889
|
else
|
743
|
-
|
890
|
+
current_viewer = @main_tabs[instance.__id__][resvwr.__id__]
|
891
|
+
if current_viewer && (index = tabs.index(current_viewer.view))
|
892
|
+
replace_view_tab(tabs,view,vwr,index)
|
893
|
+
else
|
894
|
+
add_view_tab(tabs,view,vwr)
|
895
|
+
end
|
896
|
+
@main_tabs[instance.__id__][resvwr.__id__] = vwr
|
744
897
|
end
|
898
|
+
tabs.set_selected_component(view)
|
745
899
|
end
|
746
900
|
|
747
901
|
def simple_value(instance,id)
|
@@ -898,6 +1052,45 @@ module TabbedPaneMethods
|
|
898
1052
|
end
|
899
1053
|
end #TabbedPaneMethods
|
900
1054
|
|
1055
|
+
class TabHistory
|
1056
|
+
def initialize(viewer)
|
1057
|
+
@h = [viewer]
|
1058
|
+
@c = 1
|
1059
|
+
end
|
1060
|
+
def <<(viewer)
|
1061
|
+
if (len = @h.length) > @c
|
1062
|
+
@h = @h[0,@c]
|
1063
|
+
end
|
1064
|
+
@h << viewer
|
1065
|
+
@c = @h.length
|
1066
|
+
end
|
1067
|
+
def curr
|
1068
|
+
@h[@c-1]
|
1069
|
+
end
|
1070
|
+
def next
|
1071
|
+
@h[@c]
|
1072
|
+
end
|
1073
|
+
def prev
|
1074
|
+
if @c >= 2
|
1075
|
+
@h[@c-2]
|
1076
|
+
end
|
1077
|
+
end
|
1078
|
+
def next!
|
1079
|
+
if @c < @h.length
|
1080
|
+
v = @h[@c]
|
1081
|
+
@c += 1
|
1082
|
+
v
|
1083
|
+
end
|
1084
|
+
end
|
1085
|
+
def prev!
|
1086
|
+
if @c > 1
|
1087
|
+
@c -= 1
|
1088
|
+
@h[@c-1]
|
1089
|
+
end
|
1090
|
+
end
|
1091
|
+
end #TabHistory
|
1092
|
+
|
1093
|
+
|
901
1094
|
# TODO: may want JComponent version that uses get/put client property?
|
902
1095
|
# TODO: had to do this, see note at set_view_viewer
|
903
1096
|
#module ComponentViewMethods
|
@@ -436,6 +436,11 @@ module NavViewerConstants
|
|
436
436
|
IFont = Font.new('Monospaced',Font::BOLD,14)
|
437
437
|
CFont = Font.new('Dialog',Font::PLAIN,14)
|
438
438
|
ResFont = Font.new('Monospaced',Font::PLAIN,12)
|
439
|
+
MouseEvent = ::Java::JavaAwtEvent::MouseEvent
|
440
|
+
BUTTON1 = MouseEvent::BUTTON1
|
441
|
+
BUTTON2 = MouseEvent::BUTTON2
|
442
|
+
BUTTON3 = MouseEvent::BUTTON3
|
443
|
+
SHIFT = MouseEvent::SHIFT_DOWN_MASK
|
439
444
|
HdrName = 'Name'.freeze
|
440
445
|
HdrVarName = 'Variable name'.freeze
|
441
446
|
HdrType = 'Type'.freeze
|
@@ -566,15 +571,15 @@ module NavViewer
|
|
566
571
|
set_font col.dfont || VFont
|
567
572
|
foreground col.dfg if col.dfg
|
568
573
|
if (click_val = col.clk)
|
569
|
-
on_mouse_clicked do
|
570
|
-
mouse_clicked(click_val)
|
571
|
-
end
|
572
574
|
on_mouse_entered do |e|
|
573
575
|
e.source.parent.background = HColor
|
574
576
|
end
|
575
577
|
on_mouse_exited do |e|
|
576
578
|
e.source.parent.background = VColor
|
577
579
|
end
|
580
|
+
on_mouse_clicked {|e| mouse_clicked(e,click_val) }
|
581
|
+
on_mouse_pressed {|e| mouse_action(e,click_val) }
|
582
|
+
on_mouse_released {|e| mouse_action(e,click_val) }
|
578
583
|
end
|
579
584
|
end
|
580
585
|
end
|
@@ -599,7 +604,10 @@ module NavViewer
|
|
599
604
|
y_glue if glue
|
600
605
|
end
|
601
606
|
|
602
|
-
def mouse_clicked(val)
|
607
|
+
def mouse_clicked(e,val=nil)
|
608
|
+
end
|
609
|
+
|
610
|
+
def mouse_action(e,val=nil)
|
603
611
|
end
|
604
612
|
|
605
613
|
end
|
@@ -550,29 +550,42 @@ end
|
|
550
550
|
class ResultListViewer < Viewer
|
551
551
|
include ValueViewerInterface
|
552
552
|
include NavViewerConstants
|
553
|
-
|
553
|
+
#:stopdoc:
|
554
|
+
Empty = '(empty)'
|
555
|
+
#:startdoc:
|
556
|
+
|
554
557
|
class ResultListItem
|
555
558
|
def initialize(id,value)
|
556
559
|
@i = id
|
557
|
-
@v = value
|
560
|
+
@v = value
|
558
561
|
end
|
559
562
|
def id
|
560
563
|
@i
|
561
564
|
end
|
562
|
-
def
|
565
|
+
def v
|
563
566
|
@v
|
564
567
|
end
|
568
|
+
alias_method :value,:v
|
569
|
+
def ==(other)
|
570
|
+
@v == other.v
|
571
|
+
end
|
572
|
+
def eql?(other)
|
573
|
+
@v.eql?(other.v)
|
574
|
+
end
|
575
|
+
def <=>(other)
|
576
|
+
@v <=> other.v
|
577
|
+
end
|
565
578
|
def to_s
|
566
579
|
@v
|
567
580
|
end
|
568
581
|
alias_method :to_str, :to_s
|
569
|
-
|
570
|
-
end
|
571
|
-
|
572
|
-
def item_value(id)
|
573
|
-
@main.simple_value(@instance,id)
|
574
|
-
end
|
582
|
+
|
583
|
+
end #ResultListItem
|
575
584
|
|
585
|
+
# def item_value(id)
|
586
|
+
# @main.simple_value(@instance,id)
|
587
|
+
# end
|
588
|
+
#
|
576
589
|
def initialize(*r,&k)
|
577
590
|
super
|
578
591
|
create_object_list
|
@@ -581,19 +594,16 @@ class ResultListViewer < Viewer
|
|
581
594
|
def create_object_list
|
582
595
|
res = @value.results
|
583
596
|
proxy = @instance.proxy
|
584
|
-
|
585
|
-
|
586
|
-
len.times do |i|
|
597
|
+
items = []
|
598
|
+
res.length.times do |i|
|
587
599
|
id = res[i]
|
588
|
-
val = nil
|
589
|
-
|
590
|
-
val =
|
591
|
-
|
592
|
-
val = 'Unavailable'
|
600
|
+
if (val = proxy.simple_value(id) rescue nil)
|
601
|
+
val.strip!
|
602
|
+
val = Empty if val.empty?
|
603
|
+
items << ResultListItem.new(id,val)
|
593
604
|
end
|
594
|
-
list[i] = ResultListItem.new(id,val)
|
595
605
|
end
|
596
|
-
|
606
|
+
@obj_list = items.sort.to_java
|
597
607
|
end
|
598
608
|
|
599
609
|
def title
|
@@ -647,8 +657,13 @@ class ResultListViewer < Viewer
|
|
647
657
|
name_value_row('Class/Module',@value.args.clazz,CFont)
|
648
658
|
if (vars = @value.args.vars) && !vars.empty?
|
649
659
|
vname = vars[0].name.to_s
|
650
|
-
|
651
|
-
vval =
|
660
|
+
vname = ' ' if vname.empty?
|
661
|
+
vval = vars[0].value || ' '
|
662
|
+
if Regexp === vval
|
663
|
+
vval = vval.inspect
|
664
|
+
elsif String === vval
|
665
|
+
vval = ' ' if vval.empty?
|
666
|
+
end
|
652
667
|
name_value_row('Variable',vname)
|
653
668
|
name_value_row('Value',vval)
|
654
669
|
end
|
@@ -682,12 +697,64 @@ class ResultListViewer < Viewer
|
|
682
697
|
super
|
683
698
|
end
|
684
699
|
|
685
|
-
def
|
700
|
+
def set_selection
|
686
701
|
if (ix = @list.selected_index) >= 0
|
687
|
-
@
|
702
|
+
@pending = ix
|
703
|
+
end
|
704
|
+
end
|
705
|
+
def send_selection(new_tab=nil)
|
706
|
+
if ix = @pending
|
707
|
+
@pending = nil
|
708
|
+
@main.show_result_object(self,@obj_list[ix].id,new_tab)
|
709
|
+
end
|
710
|
+
end
|
711
|
+
def list_clicked(e)
|
712
|
+
list = @list
|
713
|
+
point = e.point
|
714
|
+
if BUTTON1 == e.button &&
|
715
|
+
(ix = list.location_to_index(point)) >= 0 &&
|
716
|
+
list.get_cell_bounds(ix,ix).contains(point)
|
717
|
+
send_selection((e.modifiers_ex & SHIFT) == SHIFT)
|
718
|
+
end
|
719
|
+
end
|
720
|
+
|
721
|
+
def list_keyed(e)
|
722
|
+
if @pending && e.action_key?
|
723
|
+
send_selection((e.modifiers_ex & SHIFT) == SHIFT)
|
724
|
+
end
|
725
|
+
end
|
726
|
+
|
727
|
+
def mouse_action(e)
|
728
|
+
if e.popup_trigger?
|
729
|
+
list = @list
|
730
|
+
point = e.point
|
731
|
+
if (ix = list.location_to_index(point)) >= 0 &&
|
732
|
+
list.get_cell_bounds(ix,ix).contains(point)
|
733
|
+
@menu_pending = ix
|
734
|
+
selection_popup.show(e.component,e.x,e.y)
|
735
|
+
end
|
688
736
|
end
|
689
737
|
end
|
690
738
|
|
739
|
+
def menu_selection(new_tab)
|
740
|
+
if ix = @menu_pending
|
741
|
+
@menu_pending = nil
|
742
|
+
@list.selected_index = ix
|
743
|
+
send_selection(new_tab)
|
744
|
+
end
|
745
|
+
end
|
746
|
+
|
747
|
+
def selection_popup
|
748
|
+
@popup ||= popup_menu 'Open item in ... ' do
|
749
|
+
menu_item 'Open in new tab' do
|
750
|
+
on_click {menu_selection true}
|
751
|
+
end
|
752
|
+
menu_item 'Open in default tab' do
|
753
|
+
on_click {menu_selection false}
|
754
|
+
end
|
755
|
+
end
|
756
|
+
end
|
757
|
+
|
691
758
|
def result_list
|
692
759
|
@list = list @obj_list do
|
693
760
|
align :LEFT
|
@@ -696,9 +763,14 @@ class ResultListViewer < Viewer
|
|
696
763
|
selection_mode :SINGLE_SELECTION
|
697
764
|
on_value_changed do |e|
|
698
765
|
unless e.value_is_adjusting
|
699
|
-
|
766
|
+
set_selection
|
700
767
|
end
|
701
|
-
end
|
768
|
+
end
|
769
|
+
on_mouse_clicked {|e| list_clicked e}
|
770
|
+
on_mouse_pressed {|e| mouse_action e}
|
771
|
+
on_mouse_released {|e| mouse_action e}
|
772
|
+
on_key_pressed {|e| list_keyed e}
|
773
|
+
on_key_released {|e| list_keyed e}
|
702
774
|
end
|
703
775
|
end
|
704
776
|
|
@@ -744,7 +816,7 @@ class ResultListViewer < Viewer
|
|
744
816
|
end
|
745
817
|
|
746
818
|
def close_view
|
747
|
-
@main.
|
819
|
+
@main.close_results_view(self)
|
748
820
|
end
|
749
821
|
end
|
750
822
|
|
@@ -818,8 +890,37 @@ class NavObjectViewer
|
|
818
890
|
end
|
819
891
|
end
|
820
892
|
|
821
|
-
def
|
822
|
-
@main.
|
893
|
+
def send_selection(id,new_tab=nil)
|
894
|
+
@main.show_linked_object(self,id,new_tab)
|
895
|
+
end
|
896
|
+
|
897
|
+
def mouse_clicked(e,id)
|
898
|
+
send_selection(id,(e.modifiers_ex & SHIFT) == SHIFT)
|
899
|
+
end
|
900
|
+
|
901
|
+
def mouse_action(e,id)
|
902
|
+
if e.popup_trigger?
|
903
|
+
@menu_pending = id
|
904
|
+
selection_popup.show(e.component,e.x,e.y)
|
905
|
+
end
|
906
|
+
end
|
907
|
+
|
908
|
+
def menu_selection(new_tab)
|
909
|
+
if id = @menu_pending
|
910
|
+
@menu_pending = nil
|
911
|
+
send_selection(id,new_tab)
|
912
|
+
end
|
913
|
+
end
|
914
|
+
|
915
|
+
def selection_popup
|
916
|
+
@popup ||= popup_menu 'Open item in ... ' do
|
917
|
+
menu_item 'Open in new tab' do
|
918
|
+
on_click {menu_selection true}
|
919
|
+
end
|
920
|
+
menu_item 'Open in default tab' do
|
921
|
+
on_click {menu_selection false}
|
922
|
+
end
|
923
|
+
end
|
823
924
|
end
|
824
925
|
|
825
926
|
|
@@ -1021,9 +1122,39 @@ class NavModuleViewer
|
|
1021
1122
|
@children
|
1022
1123
|
end
|
1023
1124
|
|
1024
|
-
def
|
1025
|
-
@main.
|
1125
|
+
def send_selection(id,new_tab=nil)
|
1126
|
+
@main.show_linked_object(self,id,new_tab)
|
1026
1127
|
end
|
1128
|
+
|
1129
|
+
def mouse_clicked(e,id)
|
1130
|
+
send_selection(id,(e.modifiers_ex & SHIFT) == SHIFT)
|
1131
|
+
end
|
1132
|
+
|
1133
|
+
def mouse_action(e,id)
|
1134
|
+
if e.popup_trigger?
|
1135
|
+
@menu_pending = id
|
1136
|
+
selection_popup.show(e.component,e.x,e.y)
|
1137
|
+
end
|
1138
|
+
end
|
1139
|
+
|
1140
|
+
def menu_selection(new_tab)
|
1141
|
+
if id = @menu_pending
|
1142
|
+
@menu_pending = nil
|
1143
|
+
send_selection(id,new_tab)
|
1144
|
+
end
|
1145
|
+
end
|
1146
|
+
|
1147
|
+
def selection_popup
|
1148
|
+
@popup ||= popup_menu 'Open item in ... ' do
|
1149
|
+
menu_item 'Open in new tab' do
|
1150
|
+
on_click {menu_selection true}
|
1151
|
+
end
|
1152
|
+
menu_item 'Open in default tab' do
|
1153
|
+
on_click {menu_selection false}
|
1154
|
+
end
|
1155
|
+
end
|
1156
|
+
end
|
1157
|
+
|
1027
1158
|
|
1028
1159
|
def view(&block)
|
1029
1160
|
@view ||= scroll_pane do
|
metadata
CHANGED
@@ -3,8 +3,8 @@ rubygems_version: 0.9.2
|
|
3
3
|
specification_version: 1
|
4
4
|
name: cheri
|
5
5
|
version: !ruby/object:Gem::Version
|
6
|
-
version: 0.0.
|
7
|
-
date: 2007-06-
|
6
|
+
version: 0.0.5
|
7
|
+
date: 2007-06-11 00:00:00 -07:00
|
8
8
|
summary: Cheri Builder Platform
|
9
9
|
require_paths:
|
10
10
|
- lib
|
@@ -75,6 +75,7 @@ files:
|
|
75
75
|
- lib/cheri/explorer.rb
|
76
76
|
- lib/cheri/html.rb
|
77
77
|
- lib/cheri/image
|
78
|
+
- lib/cheri/image/Back24.gif
|
78
79
|
- lib/cheri/image/cheri_icon_16x16.png
|
79
80
|
- lib/cheri/image/cheri_icon_24x24.png
|
80
81
|
- lib/cheri/image/cheri_logo_medium.png
|
@@ -90,6 +91,7 @@ files:
|
|
90
91
|
- lib/cheri/image/Delete24.gif
|
91
92
|
- lib/cheri/image/Find24.gif
|
92
93
|
- lib/cheri/image/FindAgain24.gif
|
94
|
+
- lib/cheri/image/Forward24.gif
|
93
95
|
- lib/cheri/image/jruby_14x16.png
|
94
96
|
- lib/cheri/image/jruby_logo.png
|
95
97
|
- lib/cheri/image/mod_tree.png
|