cheri 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
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