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.
Files changed (79) hide show
  1. data/MIT-LICENSE +20 -0
  2. data/README +98 -0
  3. data/Rakefile +121 -0
  4. data/examples/hello_world_1.rb +28 -0
  5. data/examples/table_1.rb +44 -0
  6. data/lib/cheri/awt.rb +41 -0
  7. data/lib/cheri/builder.rb +31 -0
  8. data/lib/cheri/builder/awt/connecter.rb +63 -0
  9. data/lib/cheri/builder/awt/constants.rb +1003 -0
  10. data/lib/cheri/builder/awt/main.rb +191 -0
  11. data/lib/cheri/builder/awt/types.rb +220 -0
  12. data/lib/cheri/builder/base.rb +533 -0
  13. data/lib/cheri/builder/config.rb +187 -0
  14. data/lib/cheri/builder/connecter.rb +386 -0
  15. data/lib/cheri/builder/context.rb +655 -0
  16. data/lib/cheri/builder/generator.rb +425 -0
  17. data/lib/cheri/builder/html/charsets.rb +154 -0
  18. data/lib/cheri/builder/html/common.rb +32 -0
  19. data/lib/cheri/builder/html/connecter.rb +57 -0
  20. data/lib/cheri/builder/html/element.rb +156 -0
  21. data/lib/cheri/builder/html/main.rb +116 -0
  22. data/lib/cheri/builder/html/types.rb +123 -0
  23. data/lib/cheri/builder/main.rb +483 -0
  24. data/lib/cheri/builder/swing/connecter.rb +141 -0
  25. data/lib/cheri/builder/swing/constants.rb +420 -0
  26. data/lib/cheri/builder/swing/main.rb +446 -0
  27. data/lib/cheri/builder/swing/types.rb +270 -0
  28. data/lib/cheri/builder/xml/charsets.rb +154 -0
  29. data/lib/cheri/builder/xml/common.rb +32 -0
  30. data/lib/cheri/builder/xml/connecter.rb +42 -0
  31. data/lib/cheri/builder/xml/element.rb +189 -0
  32. data/lib/cheri/builder/xml/main.rb +130 -0
  33. data/lib/cheri/builder/xml/types.rb +36 -0
  34. data/lib/cheri/cheri.rb +70 -0
  35. data/lib/cheri/cjx.rb +3 -0
  36. data/lib/cheri/explorer.rb +32 -0
  37. data/lib/cheri/explorer/explorer.rb +560 -0
  38. data/lib/cheri/html.rb +31 -0
  39. data/lib/cheri/image/Delete24.gif +0 -0
  40. data/lib/cheri/image/Find24.gif +0 -0
  41. data/lib/cheri/image/FindAgain24.gif +0 -0
  42. data/lib/cheri/image/Refresh24.gif +0 -0
  43. data/lib/cheri/image/Search24.gif +0 -0
  44. data/lib/cheri/image/Thumbs.db +0 -0
  45. data/lib/cheri/image/cheri_icon_16x16.png +0 -0
  46. data/lib/cheri/image/cheri_icon_24x24.png +0 -0
  47. data/lib/cheri/image/cheri_logo_medium.png +0 -0
  48. data/lib/cheri/image/close_10x10.png +0 -0
  49. data/lib/cheri/image/close_10x10s.png +0 -0
  50. data/lib/cheri/image/close_12x12.png +0 -0
  51. data/lib/cheri/image/close_14x14.png +0 -0
  52. data/lib/cheri/image/close_24x24.png +0 -0
  53. data/lib/cheri/image/close_dim2_12x12.png +0 -0
  54. data/lib/cheri/image/close_dim_12x12.png +0 -0
  55. data/lib/cheri/image/cls_tree.png +0 -0
  56. data/lib/cheri/image/con_tree.png +0 -0
  57. data/lib/cheri/image/jruby_14x16.png +0 -0
  58. data/lib/cheri/image/jruby_logo.png +0 -0
  59. data/lib/cheri/image/mod_tree.png +0 -0
  60. data/lib/cheri/image/obj_tree.png +0 -0
  61. data/lib/cheri/image/ruby_16x16.png +0 -0
  62. data/lib/cheri/image/vars_tree.png +0 -0
  63. data/lib/cheri/java.rb +26 -0
  64. data/lib/cheri/java/builder.rb +28 -0
  65. data/lib/cheri/java/builder/main.rb +407 -0
  66. data/lib/cheri/java/builder/util.rb +480 -0
  67. data/lib/cheri/java/java.rb +56 -0
  68. data/lib/cheri/jruby.rb +32 -0
  69. data/lib/cheri/jruby/explorer.rb +43 -0
  70. data/lib/cheri/jruby/explorer/common.rb +38 -0
  71. data/lib/cheri/jruby/explorer/dialogs.rb +383 -0
  72. data/lib/cheri/jruby/explorer/explorer.rb +904 -0
  73. data/lib/cheri/jruby/explorer/splash.rb +80 -0
  74. data/lib/cheri/jruby/explorer/viewer.rb +619 -0
  75. data/lib/cheri/jruby/explorer/viewers.rb +1057 -0
  76. data/lib/cheri/jruby/jruby.rb +59 -0
  77. data/lib/cheri/swing.rb +41 -0
  78. data/lib/cheri/xml.rb +31 -0
  79. 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