cheri 0.0.2
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/MIT-LICENSE +20 -0
- data/README +98 -0
- data/Rakefile +121 -0
- data/examples/hello_world_1.rb +28 -0
- data/examples/table_1.rb +44 -0
- data/lib/cheri/awt.rb +41 -0
- data/lib/cheri/builder.rb +31 -0
- data/lib/cheri/builder/awt/connecter.rb +63 -0
- data/lib/cheri/builder/awt/constants.rb +1003 -0
- data/lib/cheri/builder/awt/main.rb +191 -0
- data/lib/cheri/builder/awt/types.rb +220 -0
- data/lib/cheri/builder/base.rb +533 -0
- data/lib/cheri/builder/config.rb +187 -0
- data/lib/cheri/builder/connecter.rb +386 -0
- data/lib/cheri/builder/context.rb +655 -0
- data/lib/cheri/builder/generator.rb +425 -0
- data/lib/cheri/builder/html/charsets.rb +154 -0
- data/lib/cheri/builder/html/common.rb +32 -0
- data/lib/cheri/builder/html/connecter.rb +57 -0
- data/lib/cheri/builder/html/element.rb +156 -0
- data/lib/cheri/builder/html/main.rb +116 -0
- data/lib/cheri/builder/html/types.rb +123 -0
- data/lib/cheri/builder/main.rb +483 -0
- data/lib/cheri/builder/swing/connecter.rb +141 -0
- data/lib/cheri/builder/swing/constants.rb +420 -0
- data/lib/cheri/builder/swing/main.rb +446 -0
- data/lib/cheri/builder/swing/types.rb +270 -0
- data/lib/cheri/builder/xml/charsets.rb +154 -0
- data/lib/cheri/builder/xml/common.rb +32 -0
- data/lib/cheri/builder/xml/connecter.rb +42 -0
- data/lib/cheri/builder/xml/element.rb +189 -0
- data/lib/cheri/builder/xml/main.rb +130 -0
- data/lib/cheri/builder/xml/types.rb +36 -0
- data/lib/cheri/cheri.rb +70 -0
- data/lib/cheri/cjx.rb +3 -0
- data/lib/cheri/explorer.rb +32 -0
- data/lib/cheri/explorer/explorer.rb +560 -0
- data/lib/cheri/html.rb +31 -0
- data/lib/cheri/image/Delete24.gif +0 -0
- data/lib/cheri/image/Find24.gif +0 -0
- data/lib/cheri/image/FindAgain24.gif +0 -0
- data/lib/cheri/image/Refresh24.gif +0 -0
- data/lib/cheri/image/Search24.gif +0 -0
- data/lib/cheri/image/Thumbs.db +0 -0
- data/lib/cheri/image/cheri_icon_16x16.png +0 -0
- data/lib/cheri/image/cheri_icon_24x24.png +0 -0
- data/lib/cheri/image/cheri_logo_medium.png +0 -0
- data/lib/cheri/image/close_10x10.png +0 -0
- data/lib/cheri/image/close_10x10s.png +0 -0
- data/lib/cheri/image/close_12x12.png +0 -0
- data/lib/cheri/image/close_14x14.png +0 -0
- data/lib/cheri/image/close_24x24.png +0 -0
- data/lib/cheri/image/close_dim2_12x12.png +0 -0
- data/lib/cheri/image/close_dim_12x12.png +0 -0
- data/lib/cheri/image/cls_tree.png +0 -0
- data/lib/cheri/image/con_tree.png +0 -0
- data/lib/cheri/image/jruby_14x16.png +0 -0
- data/lib/cheri/image/jruby_logo.png +0 -0
- data/lib/cheri/image/mod_tree.png +0 -0
- data/lib/cheri/image/obj_tree.png +0 -0
- data/lib/cheri/image/ruby_16x16.png +0 -0
- data/lib/cheri/image/vars_tree.png +0 -0
- data/lib/cheri/java.rb +26 -0
- data/lib/cheri/java/builder.rb +28 -0
- data/lib/cheri/java/builder/main.rb +407 -0
- data/lib/cheri/java/builder/util.rb +480 -0
- data/lib/cheri/java/java.rb +56 -0
- data/lib/cheri/jruby.rb +32 -0
- data/lib/cheri/jruby/explorer.rb +43 -0
- data/lib/cheri/jruby/explorer/common.rb +38 -0
- data/lib/cheri/jruby/explorer/dialogs.rb +383 -0
- data/lib/cheri/jruby/explorer/explorer.rb +904 -0
- data/lib/cheri/jruby/explorer/splash.rb +80 -0
- data/lib/cheri/jruby/explorer/viewer.rb +619 -0
- data/lib/cheri/jruby/explorer/viewers.rb +1057 -0
- data/lib/cheri/jruby/jruby.rb +59 -0
- data/lib/cheri/swing.rb +41 -0
- data/lib/cheri/xml.rb +31 -0
- metadata +135 -0
@@ -0,0 +1,904 @@
|
|
1
|
+
#--
|
2
|
+
# Copyright (C) 2007 William N Dortch <bill.dortch@gmail.com>
|
3
|
+
#
|
4
|
+
# Permission is hereby granted, free of charge, to any person obtaining
|
5
|
+
# a copy of this software and associated documentation files (the
|
6
|
+
# "Software"), to deal in the Software without restriction, including
|
7
|
+
# without limitation the rights to use, copy, modify, merge, publish,
|
8
|
+
# distribute, sublicense, and/or sell copies of the Software, and to
|
9
|
+
# permit persons to whom the Software is furnished to do so, subject to
|
10
|
+
# the following conditions:
|
11
|
+
#
|
12
|
+
# The above copyright notice and this permission notice shall be
|
13
|
+
# included in all copies or substantial portions of the Software.
|
14
|
+
#
|
15
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
16
|
+
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
17
|
+
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
18
|
+
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
19
|
+
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
20
|
+
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
21
|
+
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
22
|
+
#++
|
23
|
+
#
|
24
|
+
|
25
|
+
module Cheri
|
26
|
+
module JRuby
|
27
|
+
module Explorer
|
28
|
+
class ExplorerException < StandardError; end
|
29
|
+
CJava = Cheri::Java
|
30
|
+
CheriIcon = CJava.cheri_icon
|
31
|
+
ClassIcon = CJava.get_icon('cls_tree.png')
|
32
|
+
ModuleIcon = CJava.get_icon('mod_tree.png')
|
33
|
+
RubyIcon = CJava.get_icon('ruby_16x16.png')
|
34
|
+
JRubyIcon = CJava.get_icon('jruby_14x16.png')
|
35
|
+
VariablesIcon = CJava.get_icon('vars_tree.png')
|
36
|
+
ConstantIcon = CJava.get_icon('con_tree.png')
|
37
|
+
ObjectIcon = CJava.get_icon('obj_tree.png')
|
38
|
+
CloseTabIcon = CJava.get_icon('close_12x12.png')
|
39
|
+
CloseTabDimIcon = CJava.get_icon('close_dim2_12x12.png')
|
40
|
+
CloseActiveIcon = CJava.get_icon('close_24x24.png')
|
41
|
+
System = ::Java::JavaLang::System
|
42
|
+
JOptionPane = ::Java::JavaxSwing::JOptionPane
|
43
|
+
|
44
|
+
# UI look-and-feel init adapted from JConsole
|
45
|
+
UIManager = ::Java::JavaxSwing::UIManager
|
46
|
+
unless System.get_property "swing.defaultlaf"
|
47
|
+
system_laf = UIManager.getSystemLookAndFeelClassName
|
48
|
+
if system_laf == "com.sun.java.swing.plaf.gtk.GTKLookAndFeel" ||
|
49
|
+
system_laf == "com.sun.java.swing.plaf.windows.WindowsLookAndFeel"
|
50
|
+
UIManager.setLookAndFeel(system_laf) rescue nil
|
51
|
+
end
|
52
|
+
end
|
53
|
+
laf_name = UIManager.getLookAndFeel.getClass.getName
|
54
|
+
LAF_IS_GTK = laf_name == "com.sun.java.swing.plaf.gtk.GTKLookAndFeel"
|
55
|
+
LAF_IS_WIN = laf_name == "com.sun.java.swing.plaf.windows.WindowsLookAndFeel"
|
56
|
+
|
57
|
+
# main entry point
|
58
|
+
def self.run
|
59
|
+
Main.new.run
|
60
|
+
end
|
61
|
+
|
62
|
+
class Main
|
63
|
+
include Cheri::Swing
|
64
|
+
System = ::Java::JavaLang::System
|
65
|
+
Thread = ::Java::JavaLang::Thread
|
66
|
+
JComponent = ::JavaxSwing::JComponent
|
67
|
+
WeakHashMap = ::Java::JavaUtil::WeakHashMap
|
68
|
+
JOptionPane = ::Java::JavaxSwing::JOptionPane
|
69
|
+
Math = ::Java::JavaLang::Math
|
70
|
+
FindIcon = CJava.get_icon('Find24.gif')
|
71
|
+
FindAgainIcon = CJava.get_icon('FindAgain24.gif')
|
72
|
+
SearchIcon = CJava.get_icon('Search24.gif')
|
73
|
+
RefreshIcon = CJava.get_icon('Refresh24.gif')
|
74
|
+
CloseIcon = CJava.get_icon('Delete24.gif')
|
75
|
+
ClassIcon = CJava.get_icon('class_16x16.png')
|
76
|
+
ModuleIcon = CJava.get_icon('mod_tree.png')
|
77
|
+
Viewers = Cheri::JRuby::Explorer
|
78
|
+
RubyExplorer = Cheri::Explorer::RubyExplorer
|
79
|
+
jver = ENV_JAVA['java.version']
|
80
|
+
Java5 = String === jver && jver >= '1.5'
|
81
|
+
Java6 = String === jver && jver >= '1.6'
|
82
|
+
|
83
|
+
# Maps viewer types into tab slots. Uncategorized viewers
|
84
|
+
# will be opened in tabs slots based on their primary type.
|
85
|
+
TypeTabMap = {
|
86
|
+
:root_node => :root_node,
|
87
|
+
:env => :misc,
|
88
|
+
:env_java => :misc,
|
89
|
+
:global_vars => :misc,
|
90
|
+
:global_const => :misc,
|
91
|
+
:config => :misc,
|
92
|
+
:object => :object,
|
93
|
+
:constant => :constant,
|
94
|
+
Class => :constant,
|
95
|
+
Module => :constant,
|
96
|
+
:results => :results,
|
97
|
+
}
|
98
|
+
# Shareable NodeType instances (for non-NodeTypeValue types).
|
99
|
+
NodeTypes = {}
|
100
|
+
TypeTabMap.keys.each do |type|
|
101
|
+
NodeTypes[type] = NodeType.new(type)
|
102
|
+
end
|
103
|
+
|
104
|
+
def initialize
|
105
|
+
swing[:auto => true]
|
106
|
+
@instances = {}
|
107
|
+
@instance_listeners = []
|
108
|
+
@main_tabs = {}
|
109
|
+
@search_tabs = {}
|
110
|
+
@main_tabs[:global] = {}
|
111
|
+
@search_tabs[:global] = {}
|
112
|
+
@local_instance = JRubyInstance.new(RubyExplorer.new,'Local','local')
|
113
|
+
add_instance(@local_instance)
|
114
|
+
end
|
115
|
+
|
116
|
+
def run
|
117
|
+
splash_screen = SplashScreen.new.splash
|
118
|
+
main_frame do |frame|
|
119
|
+
cherify(splash_screen)
|
120
|
+
end
|
121
|
+
bounds = @main_frame.graphics_configuration.bounds
|
122
|
+
@main_frame.set_location(Math.max(0,(bounds.width - 800)/2), Math.max(0,(bounds.height - 760)/2))
|
123
|
+
@main_frame.show
|
124
|
+
@main_frame.to_front
|
125
|
+
sleep 2
|
126
|
+
@main_tree.selection_row = 0
|
127
|
+
@main_frame.content_pane.remove(splash_screen)
|
128
|
+
@main_menu.visible = true
|
129
|
+
@main_tool_bar.visible = true
|
130
|
+
@main_panel.visible = true
|
131
|
+
@footer_panel.visible = true
|
132
|
+
@search_tab_pane.visible = false
|
133
|
+
end
|
134
|
+
|
135
|
+
def release_resources
|
136
|
+
#puts 'release_resources called'
|
137
|
+
end
|
138
|
+
|
139
|
+
def main_frame(&block)
|
140
|
+
@main_frame ||= frame 'Cheri::JRuby::Explorer' do |frame|
|
141
|
+
size 800,600
|
142
|
+
box_layout frame, :Y_AXIS
|
143
|
+
#content_pane do box_layout frame, :Y_AXIS; end
|
144
|
+
on_window_closing do
|
145
|
+
release_resources
|
146
|
+
@main_frame.dispose
|
147
|
+
end
|
148
|
+
main_menu_bar
|
149
|
+
main_tool_bar
|
150
|
+
main_panel do
|
151
|
+
main_splitter do
|
152
|
+
left_pane do
|
153
|
+
main_tree_pane do
|
154
|
+
main_tree
|
155
|
+
end
|
156
|
+
end
|
157
|
+
right_pane do
|
158
|
+
right_splitter do
|
159
|
+
main_tab_pane
|
160
|
+
search_tab_pane
|
161
|
+
end
|
162
|
+
end
|
163
|
+
end
|
164
|
+
end
|
165
|
+
footer_panel
|
166
|
+
end
|
167
|
+
cheri_yield(@main_frame,&block) if block
|
168
|
+
@main_frame
|
169
|
+
end
|
170
|
+
|
171
|
+
def main_menu_bar(&block)
|
172
|
+
@main_menu ||= menu_bar do |bar|
|
173
|
+
visible false
|
174
|
+
file_menu
|
175
|
+
connect_menu
|
176
|
+
view_menu
|
177
|
+
search_menu
|
178
|
+
help_menu
|
179
|
+
end
|
180
|
+
cheri_yield(@main_menu,&block) if block
|
181
|
+
@main_menu
|
182
|
+
end
|
183
|
+
|
184
|
+
def file_menu(&block)
|
185
|
+
@file_menu ||= menu 'File' do |menu|
|
186
|
+
mnemonic :VK_F
|
187
|
+
menu_item 'Exit' do |item|
|
188
|
+
mnemonic :VK_X
|
189
|
+
on_click do |e|
|
190
|
+
release_resources
|
191
|
+
@main_frame.dispose
|
192
|
+
end
|
193
|
+
end
|
194
|
+
end
|
195
|
+
cheri_yield(@file_menu,&block) if block
|
196
|
+
@file_menu
|
197
|
+
end
|
198
|
+
|
199
|
+
def connect_menu(&block)
|
200
|
+
@connect_menu ||= menu 'Connect' do |mn|
|
201
|
+
mnemonic :VK_C
|
202
|
+
menu_item 'New connection ...' do
|
203
|
+
on_click do
|
204
|
+
connection_dialog.show
|
205
|
+
end
|
206
|
+
end
|
207
|
+
end
|
208
|
+
cheri_yield(@connect_menu,&block) if block
|
209
|
+
@connect_menu
|
210
|
+
end
|
211
|
+
|
212
|
+
def view_menu(&block)
|
213
|
+
@view_menu ||= menu 'View' do |mn|
|
214
|
+
mnemonic :VK_V
|
215
|
+
@search_results_select = check_box_menu_item 'Search Results pane' do
|
216
|
+
selected true
|
217
|
+
on_click do |e|
|
218
|
+
if (@search_tab_pane.visible = e.source.selected = !@search_tab_pane.visible)
|
219
|
+
adjust_right_splitter
|
220
|
+
end
|
221
|
+
end
|
222
|
+
end
|
223
|
+
separator
|
224
|
+
button_group do
|
225
|
+
radio_button_menu_item 'Wrap Tabs', true do
|
226
|
+
mnemonic :VK_W
|
227
|
+
on_click do |e|
|
228
|
+
cheri_yield @main_tab_pane do tab_layout_policy :WRAP_TAB_LAYOUT; end
|
229
|
+
end
|
230
|
+
end
|
231
|
+
radio_button_menu_item 'Scroll Tabs' do
|
232
|
+
mnemonic :VK_S
|
233
|
+
on_click do |e|
|
234
|
+
cheri_yield @main_tab_pane do tab_layout_policy :SCROLL_TAB_LAYOUT; end
|
235
|
+
end
|
236
|
+
end
|
237
|
+
end #button_group
|
238
|
+
separator
|
239
|
+
menu_item 'Refresh active view' do
|
240
|
+
on_click do
|
241
|
+
refresh_active_view
|
242
|
+
end
|
243
|
+
end
|
244
|
+
menu_item 'Close active view' do
|
245
|
+
on_click do
|
246
|
+
close_active_view
|
247
|
+
end
|
248
|
+
end
|
249
|
+
end
|
250
|
+
cheri_yield(@view_menu,&block) if block
|
251
|
+
@view_menu
|
252
|
+
end
|
253
|
+
|
254
|
+
def search_menu(&block)
|
255
|
+
@search_menu ||= menu 'Search' do |mn|
|
256
|
+
mnemonic :VK_S
|
257
|
+
menu_item 'Search ObjectSpace ...' do
|
258
|
+
mnemonic :VK_S
|
259
|
+
on_click do
|
260
|
+
show_search_dialog
|
261
|
+
end
|
262
|
+
|
263
|
+
end
|
264
|
+
end
|
265
|
+
cheri_yield(@search_menu,&block) if block
|
266
|
+
@search_menu
|
267
|
+
end
|
268
|
+
|
269
|
+
def help_menu(&block)
|
270
|
+
@help_menu ||= menu 'Help' do |menu|
|
271
|
+
mnemonic :VK_H
|
272
|
+
menu_item 'About ...' do |item|
|
273
|
+
mnemonic :VK_X
|
274
|
+
on_click do |e|
|
275
|
+
show_about_dialog
|
276
|
+
end
|
277
|
+
end
|
278
|
+
end
|
279
|
+
cheri_yield(@help_menu,&block) if block
|
280
|
+
@help_menu
|
281
|
+
end
|
282
|
+
|
283
|
+
def main_tool_bar(&block)
|
284
|
+
@main_tool_bar = tool_bar 'CJRX Tools' do |tbar|
|
285
|
+
box_layout tbar, :X_AXIS
|
286
|
+
align :LEFT
|
287
|
+
floatable false
|
288
|
+
visible false
|
289
|
+
matte_border 0,0,2,0,tbar.background.darker
|
290
|
+
button RefreshIcon do
|
291
|
+
tool_tip_text 'Refresh active view'
|
292
|
+
on_click do
|
293
|
+
refresh_active_view
|
294
|
+
end
|
295
|
+
end
|
296
|
+
button FindIcon do
|
297
|
+
tool_tip_text 'Search ObjectSpace'
|
298
|
+
on_click do
|
299
|
+
show_search_dialog
|
300
|
+
end
|
301
|
+
end
|
302
|
+
button FindAgainIcon
|
303
|
+
button SearchIcon
|
304
|
+
x_glue
|
305
|
+
button CloseActiveIcon do
|
306
|
+
tool_tip_text 'Close active view'
|
307
|
+
on_click do
|
308
|
+
close_active_view
|
309
|
+
end
|
310
|
+
end
|
311
|
+
#x_glue
|
312
|
+
x_spacer 10
|
313
|
+
end
|
314
|
+
cheri_yield(@main_tool_bar,&block) if block
|
315
|
+
@main_tool_bar
|
316
|
+
end
|
317
|
+
|
318
|
+
def main_splitter(&block)
|
319
|
+
@main_splitter ||= split_pane :HORIZONTAL_SPLIT do |spane|
|
320
|
+
empty_border 4,3,0,0
|
321
|
+
align :LEFT
|
322
|
+
divider_location 200
|
323
|
+
end
|
324
|
+
cheri_yield(@main_splitter,&block) if block
|
325
|
+
@main_splitter
|
326
|
+
end
|
327
|
+
|
328
|
+
def right_splitter(&block)
|
329
|
+
@right_splitter ||= split_pane :VERTICAL_SPLIT do |spane|
|
330
|
+
align :LEFT
|
331
|
+
divider_location 450
|
332
|
+
end
|
333
|
+
cheri_yield(@right_splitter,&block) if block
|
334
|
+
@right_splitter
|
335
|
+
end
|
336
|
+
|
337
|
+
def adjust_right_splitter
|
338
|
+
if @right_splitter.divider_location > (max = @right_splitter.maximum_divider_location - 120)
|
339
|
+
@right_splitter.divider_location = max
|
340
|
+
end
|
341
|
+
end
|
342
|
+
|
343
|
+
def left_pane(&block)
|
344
|
+
@left_pane ||= y_panel
|
345
|
+
cheri_yield(@left_pane,&block) if block
|
346
|
+
@left_pane
|
347
|
+
end
|
348
|
+
|
349
|
+
def right_pane(&block)
|
350
|
+
@right_pane ||= y_panel
|
351
|
+
cheri_yield(@right_pane,&block) if block
|
352
|
+
@right_pane
|
353
|
+
end
|
354
|
+
|
355
|
+
def main_tree_pane(&block)
|
356
|
+
@main_tree_pane ||= scroll_pane
|
357
|
+
cheri_yield(@main_tree_pane,&block) if block
|
358
|
+
@main_tree_pane
|
359
|
+
end
|
360
|
+
|
361
|
+
def main_tab_pane(&block)
|
362
|
+
unless @main_tab_pane
|
363
|
+
@main_tab_pane = tabbed_pane
|
364
|
+
@main_tab_pane.extend TabbedPaneMethods
|
365
|
+
end
|
366
|
+
cheri_yield(@main_tab_pane,&block) if block
|
367
|
+
@main_tab_pane
|
368
|
+
end
|
369
|
+
|
370
|
+
def search_tab_pane(&block)
|
371
|
+
unless @search_tab_pane
|
372
|
+
@search_tab_pane = tabbed_pane do
|
373
|
+
align :LEFT
|
374
|
+
end
|
375
|
+
@search_tab_pane.extend TabbedPaneMethods
|
376
|
+
end
|
377
|
+
cheri_yield(@search_tab_pane,&block) if block
|
378
|
+
@search_tab_pane
|
379
|
+
end
|
380
|
+
|
381
|
+
def main_panel(&block)
|
382
|
+
@main_panel ||= y_panel do # superflous?
|
383
|
+
align :LEFT
|
384
|
+
visible false
|
385
|
+
end
|
386
|
+
cheri_yield(@main_panel,&block) if block
|
387
|
+
@main_panel
|
388
|
+
end
|
389
|
+
|
390
|
+
def footer_panel(&block)
|
391
|
+
@footer_panel ||= x_panel do
|
392
|
+
align :LEFT
|
393
|
+
visible false
|
394
|
+
label '' do align :CENTER; end
|
395
|
+
end
|
396
|
+
cheri_yield(@footer_panel,&block) if block
|
397
|
+
@footer_panel
|
398
|
+
end
|
399
|
+
|
400
|
+
def main_tree_model(&block)
|
401
|
+
@main_tree_model ||= default_tree_model root_tree_node
|
402
|
+
end
|
403
|
+
|
404
|
+
def main_tree(&block)
|
405
|
+
@main_tree ||= tree main_tree_model do |t|
|
406
|
+
root_tree_node do
|
407
|
+
new_instance_node @local_instance, :tree => t
|
408
|
+
end
|
409
|
+
cell_renderer ExplorerTreeCellRenderer.new
|
410
|
+
selection_model do
|
411
|
+
selection_mode :SINGLE_TREE_SELECTION
|
412
|
+
end
|
413
|
+
on_value_changed do |e|
|
414
|
+
update_selected_node_view
|
415
|
+
end
|
416
|
+
on_tree_will_expand do |e|
|
417
|
+
node = e.path.last_path_component
|
418
|
+
prepare_for_node_expansion(node) if ParentViewerInterface === node.user_object
|
419
|
+
end
|
420
|
+
# on_mouse_clicked do |e|
|
421
|
+
# end
|
422
|
+
end
|
423
|
+
cheri_yield(@main_tree,&block) if block
|
424
|
+
@main_tree
|
425
|
+
end
|
426
|
+
|
427
|
+
def root_tree_node(&block)
|
428
|
+
@root_tree_node ||= ExplorerTreeNode.new viewer(:root_node).new(NodeTypes[:root_node],self,nil,@instances)
|
429
|
+
cheri_yield(@root_tree_node,&block) if block
|
430
|
+
@root_tree_node
|
431
|
+
end
|
432
|
+
|
433
|
+
def new_tree_node(viewer,*r,&block)
|
434
|
+
tree_node = ExplorerTreeNode.new(viewer)
|
435
|
+
cherify(tree_node,*r,&block)
|
436
|
+
tree_node
|
437
|
+
end
|
438
|
+
|
439
|
+
def new_instance_node(instance,*r,&block)
|
440
|
+
type = instance.type
|
441
|
+
node = new_tree_node(viewer(type).new(nil,self,instance),*r,&block)
|
442
|
+
instance.tree_node = node
|
443
|
+
# TODO: add mechanism to define instance sub-nodes so custom nodes may be added
|
444
|
+
cheri_yield(node) do
|
445
|
+
new_tree_node(viewer(:env).new(NodeTypes[:env],self,instance))
|
446
|
+
new_tree_node(viewer(:env_java).new(NodeTypes[:env_java],self,instance)) if :jruby_instance == type
|
447
|
+
new_tree_node(viewer(:config).new(NodeTypes[:config],self,instance))
|
448
|
+
new_tree_node(viewer(:global_vars).new(NodeTypes[:global_vars],self,instance))
|
449
|
+
new_tree_node(viewer(:global_const).new(NodeTypes[:global_const],self,instance))
|
450
|
+
end
|
451
|
+
node
|
452
|
+
end
|
453
|
+
|
454
|
+
def add_instance_node(instance)
|
455
|
+
root_tree_node do
|
456
|
+
new_instance_node instance
|
457
|
+
end
|
458
|
+
end
|
459
|
+
|
460
|
+
def update_selected_node_view
|
461
|
+
node = main_tree.last_selected_path_component
|
462
|
+
return unless node && node.respond_to?(:user_object) && (viewer = node.user_object)
|
463
|
+
view = viewer.view
|
464
|
+
tabs = main_tab_pane
|
465
|
+
unless tabs.include?(view)
|
466
|
+
set_view_viewer(view,viewer)
|
467
|
+
instance = viewer.instance || :global
|
468
|
+
ntype = viewer.type.type
|
469
|
+
tab_type = TypeTabMap[ntype] || ntype
|
470
|
+
current_viewer = @main_tabs[instance][tab_type]
|
471
|
+
if current_viewer && (ix = tabs.index(current_viewer.view))
|
472
|
+
tabs[ix] = view
|
473
|
+
if Java6 && (tab = viewer.tab)
|
474
|
+
tabs[ix,:tab] = tab
|
475
|
+
else
|
476
|
+
tabs[ix,:title] = viewer.title_tab
|
477
|
+
tabs[ix,:icon] = viewer.icon_tab
|
478
|
+
end
|
479
|
+
else
|
480
|
+
cheri_yield tabs do
|
481
|
+
if Java6 && (tab = viewer.tab)
|
482
|
+
cherify(view, :tab => tab)
|
483
|
+
else
|
484
|
+
cherify(view, :title => viewer.title_tab, :icon => viewer.icon_tab)
|
485
|
+
end
|
486
|
+
end
|
487
|
+
end
|
488
|
+
@main_tabs[instance][tab_type] = viewer
|
489
|
+
end
|
490
|
+
tabs.set_selected_component(view)
|
491
|
+
end
|
492
|
+
|
493
|
+
def prepare_for_node_expansion(node)
|
494
|
+
unless node.child_count > 0
|
495
|
+
vwr = node.user_object
|
496
|
+
vwr.load_children unless vwr.children_loaded?
|
497
|
+
instance = vwr.instance
|
498
|
+
children = vwr.children
|
499
|
+
tree = @main_tree
|
500
|
+
cheri_yield node do
|
501
|
+
children.each do |ntv|
|
502
|
+
if NodeType === ntv && (clazz = viewer(ntv.type,ntv.subtype))
|
503
|
+
if NodeTypeValue === ntv
|
504
|
+
# TODO: passing value twice, because the ValueViewerInterface
|
505
|
+
# currently requires it as separate arg. rethink interface.
|
506
|
+
nvwr = clazz.new(ntv,self,instance,ntv.value)
|
507
|
+
else
|
508
|
+
nvwr = clazz.new(ntv,self,instance)
|
509
|
+
end
|
510
|
+
new_tree_node nvwr, :tree => tree
|
511
|
+
else
|
512
|
+
warn "can't create node/viewer for #{ntv}"
|
513
|
+
end
|
514
|
+
end
|
515
|
+
end
|
516
|
+
end
|
517
|
+
end
|
518
|
+
|
519
|
+
def set_view_viewer(view,viewer)
|
520
|
+
# TODO: JRuby TODO: proxy not rematched with object when object returned from Java
|
521
|
+
#view.extend ComponentViewMethods unless ComponentViewMethods === view
|
522
|
+
#view.viewer = viewer
|
523
|
+
raise Cheri.type_error(view,JComponent) unless JComponent === view
|
524
|
+
view.put_client_property(:viewer,viewer)
|
525
|
+
end
|
526
|
+
|
527
|
+
def view_viewer(view)
|
528
|
+
view.get_client_property(:viewer)
|
529
|
+
end
|
530
|
+
|
531
|
+
def refresh_active_view
|
532
|
+
if (viewer = main_tab_pane.active_viewer)
|
533
|
+
viewer.refresh if viewer.respond_to?(:refresh)
|
534
|
+
end
|
535
|
+
end
|
536
|
+
|
537
|
+
def close_active_view
|
538
|
+
if (viewer = main_tab_pane.active_viewer)
|
539
|
+
close_view(viewer)
|
540
|
+
end
|
541
|
+
end
|
542
|
+
|
543
|
+
def close_view(viewer)
|
544
|
+
view = viewer.view
|
545
|
+
main_tab_pane.remove(view)
|
546
|
+
instance = viewer.instance || :global
|
547
|
+
ntype = viewer.type.type
|
548
|
+
tab_type = TypeTabMap[ntype] || ntype
|
549
|
+
@main_tabs[instance].delete(tab_type) if @main_tabs[instance][tab_type] == viewer
|
550
|
+
@main_tabs[instance].delete(viewer.__id__)
|
551
|
+
end
|
552
|
+
|
553
|
+
def close_search_view(viewer)
|
554
|
+
view = viewer.view
|
555
|
+
search_tab_pane.remove(view)
|
556
|
+
instance = viewer.instance || :global
|
557
|
+
ntype = viewer.type.type
|
558
|
+
tab_type = TypeTabMap[ntype] || ntype
|
559
|
+
@search_tabs[instance].delete(tab_type) if @search_tabs[instance][tab_type] == viewer
|
560
|
+
@search_tabs[instance].delete(viewer.__id__)
|
561
|
+
end
|
562
|
+
|
563
|
+
def close_views_for_instance(inst)
|
564
|
+
# TODO: search views
|
565
|
+
views = main_tab_pane.select {|view| view_viewer(view).instance == inst}
|
566
|
+
views.each do |view|
|
567
|
+
close_view(view_viewer(view))
|
568
|
+
end
|
569
|
+
views = search_tab_pane.select {|view| view_viewer(view).instance == inst}
|
570
|
+
views.each do |view|
|
571
|
+
close_search_view(view_viewer(view))
|
572
|
+
end
|
573
|
+
end
|
574
|
+
|
575
|
+
def open_search_view(viewer)
|
576
|
+
view = viewer.view
|
577
|
+
tabs = search_tab_pane
|
578
|
+
set_view_viewer(view,viewer)
|
579
|
+
instance = viewer.instance || :global
|
580
|
+
ntype = viewer.type.type
|
581
|
+
tab_type = TypeTabMap[ntype] || ntype
|
582
|
+
cheri_yield tabs do
|
583
|
+
if Java6 && (tab = viewer.tab)
|
584
|
+
cherify(view, :tab => tab)
|
585
|
+
else
|
586
|
+
cherify(view, :title => viewer.title_tab, :icon => viewer.icon_tab)
|
587
|
+
end
|
588
|
+
end
|
589
|
+
@search_tabs[instance][tab_type] = viewer
|
590
|
+
tabs.set_selected_component(view)
|
591
|
+
show_search_results
|
592
|
+
end
|
593
|
+
|
594
|
+
def show_search_results
|
595
|
+
@search_tab_pane.visible = true
|
596
|
+
@search_results_select.selected = true
|
597
|
+
adjust_right_splitter
|
598
|
+
end
|
599
|
+
|
600
|
+
def add_instance(instance)
|
601
|
+
@instances[instance.address] = instance
|
602
|
+
@main_tabs[instance] = {}
|
603
|
+
@search_tabs[instance] = {}
|
604
|
+
@instance_listeners.each do |lst|
|
605
|
+
lst.instance_added(instance)
|
606
|
+
end
|
607
|
+
end
|
608
|
+
|
609
|
+
def remove_instance(inst)
|
610
|
+
close_views_for_instance(inst)
|
611
|
+
main_tree_model.remove_node_from_parent(inst.tree_node) if inst.tree_node
|
612
|
+
@instances.delete(inst.address)
|
613
|
+
@main_tabs.delete(inst)
|
614
|
+
@search_tabs.delete(inst)
|
615
|
+
@instance_listeners.each do |lst|
|
616
|
+
lst.instance_removed(inst)
|
617
|
+
end
|
618
|
+
end
|
619
|
+
|
620
|
+
def add_instance_listener(lst)
|
621
|
+
if InstanceListener === lst
|
622
|
+
@instance_listeners << lst unless @instance_listeners.include?(lst)
|
623
|
+
end
|
624
|
+
end
|
625
|
+
|
626
|
+
def remove_instance_listener(lst)
|
627
|
+
@instance_listeners.delete(lst)
|
628
|
+
end
|
629
|
+
|
630
|
+
def instance_list
|
631
|
+
@instances.values.sort {|a,b| (a.name||a.address) <=> (b.name||b.address) }
|
632
|
+
end
|
633
|
+
|
634
|
+
def viewer(type,subtype=nil)
|
635
|
+
Viewers.viewer(type,subtype)
|
636
|
+
end
|
637
|
+
|
638
|
+
def new_connection(port,name,host='localhost')
|
639
|
+
raise ArgumentError,"invalid port: #{port}" unless (pnum = Integer(port) rescue nil)
|
640
|
+
uri = "druby://#{host}:#{pnum}"
|
641
|
+
# make sure we can connect before proceeding
|
642
|
+
# TODO: need to wrap proxy for error handling
|
643
|
+
proxy = nil
|
644
|
+
begin
|
645
|
+
proxy = DRbObject.new_with_uri(uri)
|
646
|
+
proxy.ruby_version
|
647
|
+
rescue
|
648
|
+
JOptionPane.show_message_dialog(@main_frame,"Unable to connect to #{uri}")
|
649
|
+
return
|
650
|
+
end
|
651
|
+
if (inst = @instances[uri])
|
652
|
+
if inst.alive?
|
653
|
+
rsp = JOptionPane.show_confirm_dialog(@main_frame,"Active connection exists for #{uri} - reset?")
|
654
|
+
return unless rsp == JOptionPane::YES_OPTION
|
655
|
+
end
|
656
|
+
remove_instance(inst)
|
657
|
+
end
|
658
|
+
if proxy.respond_to?(:jruby_version)
|
659
|
+
inst = JRubyInstance.new(proxy,name,uri)
|
660
|
+
else
|
661
|
+
inst = RubyInstance.new(proxy,name,uri)
|
662
|
+
end
|
663
|
+
add_instance(inst)
|
664
|
+
|
665
|
+
new_node = nil
|
666
|
+
root_tree_node do
|
667
|
+
new_node = new_instance_node inst, :tree => @main_tree
|
668
|
+
end
|
669
|
+
new_node
|
670
|
+
end
|
671
|
+
|
672
|
+
def connection_dialog
|
673
|
+
@connection_dialog ||= ConnectionDialog.new(self)
|
674
|
+
end
|
675
|
+
|
676
|
+
def new_search(instance,clazz,var,value)
|
677
|
+
raise Cheri.type_error(clazz,RubyInstance) unless RubyInstance === instance
|
678
|
+
raise ArgumentError, "invalid class name #{clazz}" unless clazz =~ /^([A-Z])((\w|::[A-Z])*)$/
|
679
|
+
raise ArgumentError, "invalid variable name #{var}" if var && var !~ /^([A-Za-z_])(\w*)$/
|
680
|
+
if var
|
681
|
+
var = ('@' + var).to_sym rescue nil
|
682
|
+
if value
|
683
|
+
if value =~ /^(\/)(.*)(\/)$/
|
684
|
+
unless (val = Regexp.new($2) rescue nil)
|
685
|
+
JOptionPane.show_message_dialog(@main_frame,"Invalid regular expression #{value}")
|
686
|
+
return
|
687
|
+
end
|
688
|
+
else
|
689
|
+
val = value
|
690
|
+
end
|
691
|
+
else
|
692
|
+
val = ''
|
693
|
+
end
|
694
|
+
nv = Cheri::Explorer::SearchNameValue.new(var,val)
|
695
|
+
args = Cheri::Explorer::SearchArgs.new(clazz,[nv])
|
696
|
+
else
|
697
|
+
args = Cheri::Explorer::SearchArgs.new(clazz)
|
698
|
+
end
|
699
|
+
res = instance.proxy.find(args)
|
700
|
+
if (res = instance.proxy.find(args))
|
701
|
+
results = Cheri::Explorer::SearchResults.new(args,res)
|
702
|
+
vwr = viewer(:results).new(NodeTypes[:results],self,instance,results)
|
703
|
+
open_search_view(vwr)
|
704
|
+
end
|
705
|
+
end
|
706
|
+
|
707
|
+
def new_find(instance,id)
|
708
|
+
if rec = instance.proxy.object(id)
|
709
|
+
ntv = case rec.clazz
|
710
|
+
when 'Class' : NodeTypeValue.new(Class,rec.value,rec)
|
711
|
+
when 'Module' : NodeTypeValue.new(Module,rec.value,rec)
|
712
|
+
else NodeTypeValue.new(:object,rec.clazz,rec)
|
713
|
+
end
|
714
|
+
if (clazz = viewer(ntv.type,ntv.subtype))
|
715
|
+
vwr = clazz.new(ntv,self,instance,ntv.value)
|
716
|
+
view = vwr.view
|
717
|
+
set_view_viewer(view,vwr)
|
718
|
+
tabs = main_tab_pane
|
719
|
+
cheri_yield tabs do
|
720
|
+
if Java6 && (tab = vwr.tab)
|
721
|
+
cherify(view, :tab => tab)
|
722
|
+
else
|
723
|
+
cherify(view, :title => vwr.title_tab, :icon => vwr.icon_tab)
|
724
|
+
end
|
725
|
+
end
|
726
|
+
@main_tabs[instance][vwr.__id__] = vwr
|
727
|
+
tabs.set_selected_component(view)
|
728
|
+
else
|
729
|
+
JOptionPane.show_message_dialog(@main_frame,"Unable to display object #{id}")
|
730
|
+
end
|
731
|
+
else
|
732
|
+
JOptionPane.show_message_dialog(@main_frame,"Unable to retrieve object #{id}")
|
733
|
+
end
|
734
|
+
end
|
735
|
+
|
736
|
+
def simple_value(instance,id)
|
737
|
+
instance.proxy.simple_value(id) rescue 'Error'
|
738
|
+
end
|
739
|
+
|
740
|
+
def search_dialog
|
741
|
+
@search_dialog ||= SearchDialog.new(self)
|
742
|
+
end
|
743
|
+
|
744
|
+
def show_search_dialog
|
745
|
+
search_dialog.show
|
746
|
+
end
|
747
|
+
|
748
|
+
def about_dialog
|
749
|
+
@about_dialog ||= AboutDialog.new(self)
|
750
|
+
end
|
751
|
+
|
752
|
+
def show_about_dialog
|
753
|
+
about_dialog.show
|
754
|
+
end
|
755
|
+
|
756
|
+
def center(parent,child)
|
757
|
+
x = parent.x + ((parent.width - child.width)/2)
|
758
|
+
y = parent.y + ((parent.height - child.height)/2)
|
759
|
+
child.set_location(x,y)
|
760
|
+
child
|
761
|
+
end
|
762
|
+
|
763
|
+
|
764
|
+
end #Main
|
765
|
+
|
766
|
+
class RubyInstance
|
767
|
+
WeakHashMap = ::Java::JavaUtil::WeakHashMap
|
768
|
+
|
769
|
+
def initialize(proxy,name,address)
|
770
|
+
@proxy = proxy
|
771
|
+
@name = name
|
772
|
+
@addr = address
|
773
|
+
# @viewers = WeakHashMap.new
|
774
|
+
end
|
775
|
+
def alive?
|
776
|
+
@proxy.ruby_version rescue nil
|
777
|
+
end
|
778
|
+
def proxy
|
779
|
+
@proxy
|
780
|
+
end
|
781
|
+
def name
|
782
|
+
@name || @addr
|
783
|
+
end
|
784
|
+
def name=(name)
|
785
|
+
@name = name
|
786
|
+
end
|
787
|
+
def address
|
788
|
+
@addr
|
789
|
+
end
|
790
|
+
def icon
|
791
|
+
RubyIcon
|
792
|
+
end
|
793
|
+
def type
|
794
|
+
:ruby_instance
|
795
|
+
end
|
796
|
+
# def viewers
|
797
|
+
# @viewers
|
798
|
+
# end
|
799
|
+
def tree_node
|
800
|
+
@node
|
801
|
+
end
|
802
|
+
def tree_node=(node)
|
803
|
+
@node = node
|
804
|
+
end
|
805
|
+
|
806
|
+
end #RubyInstance
|
807
|
+
|
808
|
+
class JRubyInstance < RubyInstance
|
809
|
+
|
810
|
+
def icon
|
811
|
+
JRubyIcon
|
812
|
+
end
|
813
|
+
|
814
|
+
def type
|
815
|
+
:jruby_instance
|
816
|
+
end
|
817
|
+
end #JRubyInstance
|
818
|
+
|
819
|
+
|
820
|
+
class ExplorerTreeNode < ::Java::javax.swing.tree.DefaultMutableTreeNode
|
821
|
+
def initialize(viewer)
|
822
|
+
super
|
823
|
+
@viewer = viewer
|
824
|
+
end
|
825
|
+
def isLeaf
|
826
|
+
@viewer.leaf?
|
827
|
+
end
|
828
|
+
def add(child)
|
829
|
+
super
|
830
|
+
end
|
831
|
+
def viewer
|
832
|
+
@viewer
|
833
|
+
end
|
834
|
+
end #ExplorerTreeNode
|
835
|
+
|
836
|
+
class ExplorerTreeCellRenderer < ::Java::javax.swing.tree.DefaultTreeCellRenderer
|
837
|
+
def getTreeCellRendererComponent(tree,node,sel,expanded,leaf,row,has_focus)
|
838
|
+
super
|
839
|
+
viewer = node.user_object
|
840
|
+
set_text viewer.title_tree
|
841
|
+
set_icon viewer.icon_tree if viewer.icon_tree
|
842
|
+
self
|
843
|
+
end
|
844
|
+
end #ExplorerTreeRenderer
|
845
|
+
|
846
|
+
module TabbedPaneMethods
|
847
|
+
include Enumerable
|
848
|
+
def views
|
849
|
+
Array.new(tab_count) {|i| component_at(i) }
|
850
|
+
end
|
851
|
+
def each
|
852
|
+
tab_count.times do |i|
|
853
|
+
yield get_component_at(i)
|
854
|
+
end if block_given?
|
855
|
+
end
|
856
|
+
def include?(view)
|
857
|
+
index_of_component(view) >= 0
|
858
|
+
end
|
859
|
+
def index(view)
|
860
|
+
(ix = index_of_component(view)) >= 0 ? ix : nil
|
861
|
+
end
|
862
|
+
def [](ix)
|
863
|
+
get_component_at(ix)
|
864
|
+
end
|
865
|
+
def []=(ix,view)
|
866
|
+
set_component_at(ix,view)
|
867
|
+
end
|
868
|
+
def []=(ix,v1,v2=nil)
|
869
|
+
if v2
|
870
|
+
case v1
|
871
|
+
when :tab : set_tab_component_at(ix,v2)
|
872
|
+
when :title : set_title_at(ix,v2)
|
873
|
+
when :icon : set_icon_at(ix,v2)
|
874
|
+
when :tooltip : set_tool_tip_text_at(ix,v2)
|
875
|
+
end
|
876
|
+
else
|
877
|
+
set_component_at(ix,v1)
|
878
|
+
end
|
879
|
+
end
|
880
|
+
def active_view
|
881
|
+
selected_component
|
882
|
+
end
|
883
|
+
def active_viewer
|
884
|
+
if (view = selected_component)
|
885
|
+
view.get_client_property(:viewer)
|
886
|
+
end
|
887
|
+
end
|
888
|
+
end #TabbedPaneMethods
|
889
|
+
|
890
|
+
# TODO: may want JComponent version that uses get/put client property?
|
891
|
+
# TODO: had to do this, see note at set_view_viewer
|
892
|
+
#module ComponentViewMethods
|
893
|
+
# def viewer
|
894
|
+
# @viewer
|
895
|
+
# end
|
896
|
+
# def viewer=(viewer)
|
897
|
+
# @viewer = viewer
|
898
|
+
# end
|
899
|
+
#end #ComponentViewMethods
|
900
|
+
|
901
|
+
|
902
|
+
end #Explorer
|
903
|
+
end #JRuby
|
904
|
+
end #Cheri
|